affinity-sdk 2.0.1__tar.gz → 2.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/CHANGELOG.md +104 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/PKG-INFO +14 -7
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/README.md +13 -6
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/company_cmds.py +30 -12
- affinity_sdk-2.0.2/affinity/cli/commands/discovery_cmds.py +243 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/list_cmds.py +152 -27
- affinity_sdk-2.0.2/affinity/cli/commands/org_cmds.py +373 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/person_cmds.py +30 -12
- affinity_sdk-2.0.2/affinity/cli/entity_search.py +258 -0
- affinity_sdk-2.0.2/affinity/cli/list_search.py +92 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/main.py +9 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/query/executor.py +368 -116
- affinity_sdk-2.0.2/affinity/cli/query/filter_text.py +52 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/query/filters.py +1 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/query/models.py +1 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/query/parser.py +35 -6
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/query/planner.py +35 -47
- affinity_sdk-2.0.2/affinity/cli/query/pushdown.py +587 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/client.py +56 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/clients/http.py +54 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/compare.py +47 -28
- affinity_sdk-2.0.2/affinity/criteria.py +421 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/filters.py +2 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/models/__init__.py +32 -0
- affinity_sdk-2.0.2/affinity/models/discovery.py +178 -0
- affinity_sdk-2.0.2/affinity/models/org.py +87 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/__init__.py +4 -0
- affinity_sdk-2.0.2/affinity/services/_discovery.py +470 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/_org_reads.py +8 -0
- affinity_sdk-2.0.2/affinity/services/_search.py +304 -0
- affinity_sdk-2.0.2/affinity/services/_single_field.py +151 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/companies.py +32 -2
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/lists.py +231 -3
- affinity_sdk-2.0.2/affinity/services/org.py +392 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/persons.py +27 -2
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/v1_only.py +183 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/cli/commands.md +115 -10
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/cli/index.md +1 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/claude-code-plugins.md +5 -5
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/csv-export.md +5 -5
- affinity_sdk-2.0.2/docs/public/guides/filtering.md +418 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/migrating-to-2.md +19 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/query-command.md +92 -21
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/api-coverage.md +26 -26
- affinity_sdk-2.0.2/docs/public/reference/filters.md +21 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/query-language.md +71 -31
- affinity_sdk-2.0.2/docs/public/reference/services/companies.md +101 -0
- affinity_sdk-2.0.2/docs/public/reference/services/lists.md +24 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/services/persons.md +15 -0
- affinity_sdk-2.0.2/docs/public/reference/services/teams-users.md +7 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.claude-plugin/plugin.json +1 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.claude-plugin/skills/affinity-mcp-workflows/SKILL.md +2 -2
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.claude-plugin/skills/query-language/SKILL.md +43 -21
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.claude-plugin/skills/query-language/references/filter-operators.md +13 -5
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.claude-plugin/skills/query-language/references/quantifiers.md +25 -17
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.gitignore +3 -0
- affinity_sdk-2.0.2/mcp/.mcp-bash/VERSION +1 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/bin/mcp-bash +59 -3
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/resources.sh +2 -2
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/tools.sh +0 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/cli/common.sh +2 -2
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/completion.sh +1 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/core.sh +128 -7
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/elicitation.sh +19 -2
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/file_read.sh +57 -17
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/io.sh +99 -14
- affinity_sdk-2.0.2/mcp/.mcp-bash/lib/lock.sh +252 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/policy.sh +7 -2
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/progress-passthrough.sh +0 -2
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/progress.sh +4 -3
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/prompts.sh +3 -4
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/registry.sh +34 -7
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/resource_match.sh +18 -3
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/resources.sh +266 -44
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/runtime.sh +58 -5
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/tools.sh +64 -100
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/ui.sh +2 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/validate.sh +10 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/providers/file.sh +12 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/providers/ui.sh +5 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/sdk/tool-sdk.sh +8 -8
- affinity_sdk-2.0.2/mcp/.mcp-bash/vendor.json +1 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.registry/commands.generated.json +516 -10
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.registry/mcp-commands.json +47 -4
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/CHANGELOG.md +31 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/COMPATIBILITY +14 -2
- affinity_sdk-2.0.2/mcp/VERSION +1 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/mcp-bash.lock +2 -2
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/data-model/data-model.md +24 -19
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/server.d/requirements.json +1 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/server.d/server.meta.json +1 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/tools/execute-read-command/tool.meta.json +1 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/tools/execute-write-command/tool.sh +4 -0
- affinity_sdk-2.0.2/mcp/tools/query/tool.meta.json +111 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mkdocs.yml +1 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/plugins/affinity-sdk/.claude-plugin/plugin.json +1 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/plugins/affinity-sdk/.claude-plugin/skills/affinity-python-sdk/SKILL.md +40 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/.claude-plugin/plugin.json +1 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/SKILL.md +11 -7
- affinity_sdk-2.0.2/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/filtering.md +79 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/query-guide.md +65 -16
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/pyproject.toml +1 -1
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_company_cmds_coverage.py +4 -3
- affinity_sdk-2.0.2/tests/test_cli_entity_ls_server_filter.py +195 -0
- affinity_sdk-2.0.2/tests/test_cli_list_export_server_filter.py +169 -0
- affinity_sdk-2.0.2/tests/test_cli_org.py +161 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_person_cmds_coverage.py +4 -3
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_query_planner.py +10 -8
- affinity_sdk-2.0.2/tests/test_cli_query_server_filter.py +334 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_compare.py +17 -3
- affinity_sdk-2.0.2/tests/test_duplicates_connections.py +277 -0
- affinity_sdk-2.0.2/tests/test_query_pushdown.py +376 -0
- affinity_sdk-2.0.2/tests/test_search_v2.py +277 -0
- affinity_sdk-2.0.2/tests/test_single_field_v2.py +150 -0
- affinity_sdk-2.0.2/tests/test_teams_users_feedback.py +235 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/api_coverage.json +50 -49
- affinity_sdk-2.0.2/tools/search_golden.py +198 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/validate_openapi_models.py +31 -0
- affinity_sdk-2.0.1/docs/public/guides/filtering.md +0 -303
- affinity_sdk-2.0.1/docs/public/reference/filters.md +0 -3
- affinity_sdk-2.0.1/docs/public/reference/services/companies.md +0 -45
- affinity_sdk-2.0.1/docs/public/reference/services/lists.md +0 -5
- affinity_sdk-2.0.1/mcp/.mcp-bash/VERSION +0 -1
- affinity_sdk-2.0.1/mcp/.mcp-bash/lib/lock.sh +0 -176
- affinity_sdk-2.0.1/mcp/.mcp-bash/vendor.json +0 -1
- affinity_sdk-2.0.1/mcp/VERSION +0 -1
- affinity_sdk-2.0.1/mcp/tools/query/tool.meta.json +0 -111
- affinity_sdk-2.0.1/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/filtering.md +0 -51
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.claude-plugin/marketplace.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.cursor/rules/test-data-privacy.mdc +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.editorconfig +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.env.example +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.gitattributes +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/CODEOWNERS +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/PULL_REQUEST_TEMPLATE/cli_command.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/PULL_REQUEST_TEMPLATE/release.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/dependabot.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/labels.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/mcp-release-install-footer.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/pull_request_template.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/release-install-footer.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/workflows/ci.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/workflows/cowork-replay.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/workflows/docs.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/workflows/labels.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/workflows/linkcheck.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/workflows/openapi-validation.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/workflows/plugin-build.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/workflows/plugin-release.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/workflows/release-detect.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/workflows/release.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.github/workflows/version-check.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.gitignore +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/.pre-commit-config.yaml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/AGENTS.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/CODE_OF_CONDUCT.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/CONTRIBUTING.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/LICENSE +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/SECURITY.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/VERSIONING.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/__init__.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/_internal/__init__.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/_internal/keyfile.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/api_versions.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/__init__.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/__main__.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/_update_worker.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/click_compat.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/__init__.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/_entity_field.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/_entity_files_dump.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/_entity_files_read.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/_entity_files_upload.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/_list_entry_fields.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/_org_reads.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/_search_common.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/_v1_parsing.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/completion_cmd.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/config_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/entry_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/field_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/file_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/file_url_cmd.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/interaction_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/note_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/opportunity_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/org_read_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/query_cmd.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/relationship_strength_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/reminder_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/resolve_url_cmd.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/session_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/task_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/transcript_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/version_cmd.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/webhook_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/commands/whoami_cmd.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/config.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/confirm.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/constants.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/context.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/csv_utils.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/date_utils.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/decorators.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/errors.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/field_utils.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/formatters.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/help_json.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/interaction_utils.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/logging.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/mcp_limits.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/options.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/paths.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/progress.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/query/__init__.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/query/aggregates.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/query/cursor.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/query/dates.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/query/exceptions.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/query/output.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/query/progress.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/query/schema.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/render.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/resolve.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/resolvers.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/results.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/runner.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/serialization.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/session_cache.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/types.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/cli/update_check.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/clients/__init__.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/clients/pipeline.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/downloads.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/exceptions.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/field_resolve_utils.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/field_resolver.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/hooks.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/inbound_webhooks.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/models/entities.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/models/interactions_v2.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/models/pagination.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/models/rate_limit_snapshot.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/models/relationships_v2.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/models/search.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/models/secondary.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/models/transcripts.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/models/types.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/policies.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/progress.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/py.typed +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/_dropdown_options.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/_field_listing.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/_field_updates.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/_note_html.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/_v2_filters.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/opportunities.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/rate_limits.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/reminders.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/search.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/tasks.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/transcripts.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/services/webhooks.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/affinity/types.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/codecov.yml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/cli-development-guide.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/ai-integrations/index.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/changelog.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/cli/scripting.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/cli-reference.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/examples.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/getting-started.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/glossary.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/affinity-official-mcp-comparison.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/api-versions-and-routing.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/api-versions.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/authentication.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/configuration.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/datetime-handling.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/debugging-hooks.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/errors-and-retries.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/field-types-and-values.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/field-values.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/ids-and-types.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/models.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/opportunity-associations.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/pagination.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/performance.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/rate-limits.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/sync-vs-async.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/guides/webhooks.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/index.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/mcp/index.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/client.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/exceptions.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/models.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/services/opportunities.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/services/reminders.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/services/tasks.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/services/v1/auth.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/services/v1/field-values.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/services/v1/fields.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/services/v1/files.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/services/v1/interactions.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/services/v1/notes.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/services/v1/relationships.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/services/webhooks.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/reference/types.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/docs/public/troubleshooting.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/examples/advanced_usage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/examples/async_lifecycle.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/examples/basic_usage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/examples/filter_builder.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/examples/hooks_debugging.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/examples/list_management.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/examples/resolve_helpers.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/examples/task_polling.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.claude-plugin/.gitignore +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.claude-plugin/skills/pipeline-history/SKILL.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.claude-plugin/skills/query-language/references/include-expand.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.claude-plugin/skills/query-language/references/output-formats.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.claude-plugin/xaffinity-mcp.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/completion.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/lifecycle.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/logging.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/ping.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/prompts.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/roots.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/auth.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/capabilities.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/cli/health.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/handler_helpers.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/hash.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/ids.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/json.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/logging.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/meta_env.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/paginate.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/path.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/require.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/resource_content.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/resource_providers.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/roots.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/rpc.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/spec.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/timeout.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/tools_policy.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/ui-templates.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/uri.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/providers/echo.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/providers/git.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/providers/https.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/sdk/tool-error.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.mcp-bash/sdk/ui-sdk.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.registry/prompts.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.registry/resource-templates.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.registry/resources.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/.registry/ui-resources.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/Makefile +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/README.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/completions/entity-name.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/completions/list-name.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/completions/status-value.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/docs/DEBUGGING.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/icon.svg +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/lib/cache.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/lib/cli-detect.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/lib/cli-gateway.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/lib/common.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/lib/entity-types.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/lib/field-resolution.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/mcp-publisher.lock +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/mcpb.conf +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/change-status/change-status.completion.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/change-status/change-status.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/change-status/change-status.txt +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/interaction-brief/interaction-brief.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/interaction-brief/interaction-brief.txt +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/log-call/log-call.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/log-call/log-call.txt +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/log-interaction-and-update-workflow/log-interaction-and-update-workflow.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/log-interaction-and-update-workflow/log-interaction-and-update-workflow.txt +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/log-message/log-message.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/log-message/log-message.txt +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/pipeline-review/pipeline-review.completion.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/pipeline-review/pipeline-review.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/pipeline-review/pipeline-review.txt +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/prepare-briefing/prepare-briefing.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/prepare-briefing/prepare-briefing.txt +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/warm-intro/warm-intro.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/prompts/warm-intro/warm-intro.txt +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/providers/xaffinity.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/data-model/data-model.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/field-catalogs/field-catalogs.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/field-catalogs/field-catalogs.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/interaction-enums/interaction-enums.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/interaction-enums/interaction-enums.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/me/me.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/me/me.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/me-person-id/me-person-id.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/me-person-id/me-person-id.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/query-guide/query-guide.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/query-guide/query-guide.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/saved-views/saved-views.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/saved-views/saved-views.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/workflow-config/workflow-config.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/workflow-config/workflow-config.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/workflows-guide/workflows-guide.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/workflows-guide/workflows-guide.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/xaffinity-field-catalogs.completion.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/xaffinity-saved-views.completion.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/resources/xaffinity-workflow-config.completion.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/server.d/env.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/server.d/health-checks.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/server.d/policy.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/server.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/test/README.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/test/run.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/test/test_env_update_check.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/test-progress.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/tools/discover-commands/tool.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/tools/discover-commands/tool.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/tools/execute-read-command/tool.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/tools/execute-write-command/tool.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/tools/get-entity-dossier/tool.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/tools/get-entity-dossier/tool.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/tools/get-file-url/tool.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/tools/get-file-url/tool.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/tools/query/tool.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/tools/read-xaffinity-resource/tool.meta.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/tools/read-xaffinity-resource/tool.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/user-config.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/xaffinity-mcp-env.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/mcp/xaffinity-mcp.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/plugins/affinity-sdk/.claude-plugin/skills/affinity-python-sdk/references/services.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/hooks/guard-env-read.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/hooks/hooks.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/hooks/pre-xaffinity.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/hooks/session-setup.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/files-and-writes.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/history-and-activity.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/interactions.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/setup.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cli/query/test_cursor.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cli/test_company_create_dedup.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cli/test_company_ls_filter_rejection.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cli/test_formatters.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cli/test_output_formats_integration.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cli/test_person_create_dedup.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cli/test_person_ls_filter_rejection.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cli/test_query_filter_rejection.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cli/test_query_list_entry_relationships.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cli/test_query_list_export_parity.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cli/test_query_output_flattening.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cli/test_query_output_truncation.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cli/test_query_unreplied.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/conftest.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/.cowork-redact.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/README.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/cassettes/company-lists-status.cassette.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/cassettes/hook-blocks-without-key.cassette.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/cassettes/no-key-skill-path.cassette.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/cassettes/status-history.cassette.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/fixtures/workdir-key/README.txt +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/fixtures/workdir-key/xaffinity-test-key +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/fixtures/workdir-nokey/README.txt +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/image/Dockerfile +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/image/fakeaff/build_fixtures.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/image/fakeaff/fixtures.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/image/fakeaff/server.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/image/xaffinity-wrapper.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/privacy-allow.txt +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/record.sh +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/scenarios/company-lists-status.yaml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/scenarios/hook-blocks-without-key.yaml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/scenarios/no-key-skill-path.yaml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/scenarios/status-history.yaml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/sessions/no-key.yaml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/cowork/sessions/with-key.yaml +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/field_write_mocks.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/fixtures/openapi/mini_openapi.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/fixtures/webhooks/field_value_updated.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/fixtures/webhooks/list_entry_created.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/fixtures/webhooks/organization_created.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/fixtures/webhooks/organization_merged.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/fixtures/webhooks/person_created.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/fixtures/webhooks/unknown_event.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/integration/README.md +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/integration/conftest.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/integration/setup_query_parity_data.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/integration/test_cli_writes.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/integration/test_query_parity_integration.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/integration/test_sdk_reads.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/integration/test_sdk_writes.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/integration/test_sdk_writes_runner.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/mcp/__init__.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/mcp/test_query_cursor.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/skill-evals/xaffinity-cli-usage-evals/evals.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/spec_guard.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_affinity_client_wrapper_additional_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_api_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_api_key_file_formats.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_api_key_resolution.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_api_version.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_api_version_per_operation.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_async_file_download_streaming.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_batch_get.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_api_version.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_column_limiting.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_command_context.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_company_get.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_config_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_context_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_csv_export.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_date_params.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_date_utils.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_datetime_formatting.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_datetime_header_offsets.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_domain_linkification.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_dotenv_resolution.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_dropdown_field_writes.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_enriched_field_writes.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_entity_field_writes.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_entity_files_dump.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_entry_field.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_entry_field_batch_writes.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_entry_field_multi_value_limits.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_error_hints.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_error_rendering.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_field_history.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_field_history_bulk.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_field_options_and_transcripts.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_field_utils.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_field_utils_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_field_utils_set_phase.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_field_value_humanization.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_file_url.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_files_ls.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_files_read.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_get_interaction_dates.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_help_json.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_interaction_date_chunking.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_interaction_utils.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_json_safety.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_list_cmds_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_list_expand_interactions.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_list_export_entity_scope.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_list_export_field_refresh.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_list_export_filter_safety.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_list_export_truncation_meta.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_missing_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_multi_value_truncation_warnings.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_no_network_commands.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_notes_writes.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_opportunity_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_opportunity_cmds_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_pager_logic.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_person_get.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_plugin_manifest.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_pre_xaffinity_hook.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_progress_manager.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_query_aggregates.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_query_cmd.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_query_cmd_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_query_dates.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_query_executor.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_query_expand_interactions.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_query_filters.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_query_integration.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_query_parser.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_query_safety.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_query_schema.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_rate_limit_rendering.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_rate_limit_throttle.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_reminders.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_render_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_resolve_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_resolve_url_parsing.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_result_summary.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_safe_field_writes.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_search.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_serialization.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_session_cache.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_session_setup_hook.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_set_phase_atomicity.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_types.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_unreplied.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_update_check.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_v1_only_cmds.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_v1_parsing.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_webhooks.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_cli_write_ops.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_client.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_companies_create_dedup.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_companies_filter_rejection.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_env_helpers.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_exceptions_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_field_resolver.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_field_service_caching.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_field_types_c4.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_field_value_type.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_field_values_get_value.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_file_batch_get.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_file_download_streaming.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_file_list_batch.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_file_upload_helpers_and_validation.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_files_upload_returning_files.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_files_v2.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_filters.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_generate_mcp_command_registry.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_get_fields_filter_includes.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_get_fields_pagination.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_get_first.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_hidden_field_values.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_hooks.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_http_client_additional_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_http_client_remaining_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_inbound_webhooks.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_integration_smoke.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_interaction_date_validation.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_interactions_and_files_regressions.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_isodatetime.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_list_entry_membership_and_opportunities.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_list_term.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_lists_v2_writes.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_mcp_bundle_env_and_completions.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_mcp_cli_version_check.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_mcp_entity_dossier.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_mcp_gateway_limits.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_mcp_history_bulk_gateway.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_mcp_limits.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_mcp_query_cli_error.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_mcp_read_truncation.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_mcp_resource_scripts.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_models.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_models_v2_2026_fields.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_multi_value_limits.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_new_features.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_notes_v2.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_notes_v2_writes.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_opportunities_filter_rejection.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_org_reads.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_pagination_iterators.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_persons_create_dedup.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_persons_filter_rejection.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_public_api.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_rate_limit_v2.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_raw_pipeline_hook_events.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_readonly_factory.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_reminder_list_batch.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_reminders_v2.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_requirements_additional.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_sdk_interaction_dates.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_search.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_service_get_parameter_combinations.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_services_companies_coverage_gaps.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_services_dropdown_options.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_services_entity_field_updates.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_services_field_value_changes.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_services_list_entries_filter_paths.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_services_lists_additional_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_services_lists_coverage_gaps.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_services_opportunities_additional_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_services_opportunities_coverage_gaps.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_services_opportunities_tasks_additional_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_services_persons_companies_additional_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_services_rate_limits_coverage_gaps.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_services_v1_only_async.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_services_v1_only_coverage_gaps.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_small_modules_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_spec_guard.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_transport_and_readonly_mode.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_v1_association_parsing.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_v1_only_services_additional_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_v1_only_services_more_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_v2_request_bodies.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_validate_openapi_tool.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/test_webhooks_v2.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/unit/__init__.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tests/unit/test_exceptions.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/__init__.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/api_coverage.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/api_coverage_v1_snapshot.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/check_cli_patterns.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/generate_mcp_command_registry.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/generate_release_notes.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/generate_requirements_mapping.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/openapi_snapshots/2024-01-01.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/openapi_snapshots/2026-07-15.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/openapi_snapshots/2026-09-17.json +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/sync_mcp_bundle_env.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/sync_mcp_registry.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/sync_mcp_version.py +0 -0
- {affinity_sdk-2.0.1 → affinity_sdk-2.0.2}/tools/validate_mcp_registry_metadata.py +0 -0
|
@@ -7,6 +7,110 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.0.2] - 2026-10-13
|
|
11
|
+
|
|
12
|
+
### Changed (breaking)
|
|
13
|
+
|
|
14
|
+
**Exception to semantic versioning:** these change what some filters return, in a patch release
|
|
15
|
+
(the maintainer's call). Filters now mean what Affinity's own search means, so the same filter
|
|
16
|
+
gives the same answer whether Affinity or the CLI applies it. This reaches Python code too:
|
|
17
|
+
`affinity.filters` (`F`, filter strings, `lists.entries(...).list/iter/pages(filter=...)`)
|
|
18
|
+
uses the same comparison rules as the CLI.
|
|
19
|
+
|
|
20
|
+
- **An empty multi-value field counts as empty.** `is_null` / `is empty` now match a field with
|
|
21
|
+
no items (`[]`), and `is_not_null` / `is not null` no longer do, in `query`, `--filter` and
|
|
22
|
+
the SDK's `affinity.filters`.
|
|
23
|
+
- **`contains` on person and company fields is refused** (in `query` on list entries): use the
|
|
24
|
+
new **`starts_word`** operator, which matches a word in the name that starts with the text,
|
|
25
|
+
the way Affinity's search does ("Jan" finds "Jane Doe"; "ane" doesn't).
|
|
26
|
+
- **`query` sorts the way Affinity's search sorts:** Affinity's order is kept when it sorts,
|
|
27
|
+
and the local sort breaks ties by id (ascending) instead of keeping fetch order.
|
|
28
|
+
- **`query`: a field name two list fields share is refused.** Name the field by id instead:
|
|
29
|
+
`fields.<field id>` (e.g. Affinity's and Dealroom's "Year Founded"). Such fields come back
|
|
30
|
+
keyed by id, instead of one silently overwriting the other. Any field can be named by id.
|
|
31
|
+
- **Person and company field values filter by name** in `--filter` and the SDK's
|
|
32
|
+
`affinity.filters` (`Owner = "Jane Doe"`, `Owner starts_word "Jan"`), as they already did in
|
|
33
|
+
`query`; before, they were compared as raw objects.
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- **`starts_word` filter operator** (`query` JSON and `--filter` text: `Owner starts_word "Jan"`).
|
|
38
|
+
|
|
39
|
+
- **Teams, users and feedback (V2):** `client.teams.list/iter/get` (Affinity API 2026-09-17+;
|
|
40
|
+
filter by name, sort, `includes` for the first members and accessible lists),
|
|
41
|
+
`client.users.list/iter/get` (internal users; `term`, `status`; a user's id is their person
|
|
42
|
+
id), `client.feedback.send(kind, subject, body)` (to Affinity's product team). New models
|
|
43
|
+
`Team`, `TeamMember`, `UserAccount`, `UserStatus`.
|
|
44
|
+
- **`interactions.get_meeting(id)`** (V2, API 2026-07-15+) and
|
|
45
|
+
**`notes.list/iter_attached_companies|persons|opportunities(note_id)`** (every entity a note
|
|
46
|
+
is attached to, beyond `get()`'s preview).
|
|
47
|
+
- **Duplicate suggestions and warm intros (V2, beta):**
|
|
48
|
+
`companies/persons.list|iter_duplicate_suggestions` (API 2026-07-15+; `term`,
|
|
49
|
+
`match_criteria`, `order_by`) and `companies.list|iter_coworker_connections(company_id)` /
|
|
50
|
+
`list|iter_investor_executive_connections(company_id)` (people at a company today whom someone
|
|
51
|
+
you know may know). CLI `company duplicates`, `person duplicates`, `company connections`.
|
|
52
|
+
- **One field at a time (V2):** `companies/persons.get_field_value(id, field_id)` (the value,
|
|
53
|
+
unwrapped) and `update_field_value(id, field_id, value, value_type=None)`;
|
|
54
|
+
`companies/persons.list|iter_field_value_items(id, field_id)` and
|
|
55
|
+
`lists.entries(list_id).list|iter_field_value_items(entry_id, field_id)` page through a
|
|
56
|
+
multi-value field's items (API 2026-09-17+); `lists.entries(list_id).list|iter_field_changes(
|
|
57
|
+
entry_id, ...)` give one entry's field change history, oldest first.
|
|
58
|
+
- **Search on Affinity's side (V2, beta):** `companies.find`, `persons.find` and
|
|
59
|
+
`lists.entries(list_id).find` (plus `iter_find`, and `find_body` for a prebuilt request
|
|
60
|
+
body) filter, sort and keyword-search on the server, so only matching records are
|
|
61
|
+
downloaded. Build filters with `affinity.criteria`: `Condition(field_id, operator, value)`,
|
|
62
|
+
`all_of`, `any_of`, `Sort`. Value types are read from the fields metadata when omitted, and
|
|
63
|
+
each operator is checked against the field. Needs the "Export All Organizations directory"
|
|
64
|
+
permission (companies, persons) or "Export data from Lists" (list entries). Allowed under
|
|
65
|
+
read-only mode.
|
|
66
|
+
- **`query` on list entries filters on Affinity's side:** conditions on list fields that
|
|
67
|
+
Affinity's search answers (dropdown and ranked-dropdown values, `!=` on dropdowns, numbers,
|
|
68
|
+
dates, text `contains`/`eq`/`starts_with`, `is_not_null` on single-value fields)
|
|
69
|
+
go to the server, so only matching entries are downloaded; the full `where` still runs
|
|
70
|
+
locally on what comes back, so results are unchanged. Everything else (related records,
|
|
71
|
+
`entityName`, `is_null`, Affinity's enriched fields, field names two fields share) is
|
|
72
|
+
filtered locally, as before. If the search is refused (for example, no "Export data from
|
|
73
|
+
Lists" permission) the query reads the whole list instead, with a warning.
|
|
74
|
+
`--include-meta` shows `meta.serverFilter` (what went to the server, and why the rest
|
|
75
|
+
didn't); `--dry-run` names the candidate fields. `XAFFINITY_QUERY_SERVER_FILTER=0` turns it
|
|
76
|
+
off.
|
|
77
|
+
- **`list export --filter` filters on Affinity's side** through the same engine as `query`:
|
|
78
|
+
the `--filter` text becomes a `query` where clause, the part Affinity's search answers is
|
|
79
|
+
sent, and the whole filter still runs locally. When Affinity applies the whole filter,
|
|
80
|
+
`--all` / `--max-results` / `--first-page-only` are no longer required (page one is the
|
|
81
|
+
first page of matches); otherwise the error's `details.local` says which conditions stay
|
|
82
|
+
local. The printed cursor (`xsearch1:...`) carries the search, so `--cursor` alone resumes
|
|
83
|
+
a filtered export. A refused search falls back to reading the whole list, with a warning.
|
|
84
|
+
- **`company ls --filter` and `person ls --filter` work** (they used to be refused): the filter
|
|
85
|
+
goes to Affinity's search, which filters on field values, and the whole filter still runs
|
|
86
|
+
locally on what comes back. A filter with no field condition is still refused (reading every
|
|
87
|
+
company isn't practical: use `--query`). Conditions on Affinity's enriched fields are sent
|
|
88
|
+
as they are, with a warning that Affinity's search can miss a few records' enriched values.
|
|
89
|
+
The cursor carries the search (`xsearch1:...`).
|
|
90
|
+
- **`query` on companies and persons can filter on their fields** (`fields.<name>`): Affinity's
|
|
91
|
+
search applies what it can, the rest of the `where` (e.g. `name contains`) runs on what comes
|
|
92
|
+
back. A `where` with no field condition is still refused (it would mean reading Affinity's
|
|
93
|
+
whole directory). `meta.serverFilter` with `--include-meta`; enriched-field conditions carry
|
|
94
|
+
a warning that a few records' enriched values can be missed.
|
|
95
|
+
- **More of `query` goes to Affinity** (list entries too): `is_null` / `is_not_null` on every
|
|
96
|
+
verified field type, multi-value fields included; multi-select dropdowns (`eq` membership,
|
|
97
|
+
`in`, `has_any`, `has_all`, `contains`/`starts_word` on option text, `!=`); `!=` on numbers;
|
|
98
|
+
and `starts_word` on a person or company
|
|
99
|
+
field (person, multi-person and multi-company fields; one per query, at the top level of the
|
|
100
|
+
`where`, plain text of 3+ letters).
|
|
101
|
+
- **`query` sorts on Affinity's side** when every `orderBy` key is a sortable field
|
|
102
|
+
(`fields.<name>`, up to 5, no `groupBy`/`aggregate`): with a `limit`, the fetch stops once
|
|
103
|
+
enough records pass the filter, instead of reading everything to sort it. This works on
|
|
104
|
+
companies and persons without a `where` too. `meta.serverFilter.sort` says so.
|
|
105
|
+
- **CLI:** `team ls|get`, `user ls|get`, `meeting get`, `note attached`, `feedback send` (asks
|
|
106
|
+
for confirmation: the text leaves your organization). The MCP registry has them; `feedback
|
|
107
|
+
send` goes through the user-confirmation flow.
|
|
108
|
+
|
|
109
|
+
### Fixed
|
|
110
|
+
|
|
111
|
+
- **`query --dry-run`** no longer claims a "server-side filter" for list entries that was never
|
|
112
|
+
applied.
|
|
113
|
+
|
|
10
114
|
## [2.0.1] - 2026-10-12
|
|
11
115
|
|
|
12
116
|
### Changed (breaking)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: affinity-sdk
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.2
|
|
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/
|
|
@@ -215,15 +215,22 @@ with Affinity.from_env() as client:
|
|
|
215
215
|
### Working with Companies
|
|
216
216
|
|
|
217
217
|
```python
|
|
218
|
-
from
|
|
218
|
+
from datetime import date
|
|
219
|
+
|
|
220
|
+
from affinity import Affinity
|
|
221
|
+
from affinity.criteria import Condition, Sort, all_of
|
|
219
222
|
from affinity.models import CompanyCreate
|
|
220
|
-
from affinity.types import CompanyId
|
|
223
|
+
from affinity.types import CompanyId
|
|
221
224
|
|
|
222
225
|
with Affinity(api_key="your-key") as client:
|
|
223
|
-
#
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
226
|
+
# Filter and sort on Affinity's side (V2 search, beta)
|
|
227
|
+
page = client.companies.find(
|
|
228
|
+
all_of(
|
|
229
|
+
Condition("field-498220", "is-any-of", [3, 4]),
|
|
230
|
+
Condition("affinity-data-last-funding-date", "is-after", date(2025, 1, 1)),
|
|
231
|
+
),
|
|
232
|
+
sort=[Sort("affinity-data-total-funding-amount", "desc")],
|
|
233
|
+
limit=50,
|
|
227
234
|
)
|
|
228
235
|
|
|
229
236
|
# Iterate through all companies with automatic pagination
|
|
@@ -154,15 +154,22 @@ with Affinity.from_env() as client:
|
|
|
154
154
|
### Working with Companies
|
|
155
155
|
|
|
156
156
|
```python
|
|
157
|
-
from
|
|
157
|
+
from datetime import date
|
|
158
|
+
|
|
159
|
+
from affinity import Affinity
|
|
160
|
+
from affinity.criteria import Condition, Sort, all_of
|
|
158
161
|
from affinity.models import CompanyCreate
|
|
159
|
-
from affinity.types import CompanyId
|
|
162
|
+
from affinity.types import CompanyId
|
|
160
163
|
|
|
161
164
|
with Affinity(api_key="your-key") as client:
|
|
162
|
-
#
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
165
|
+
# Filter and sort on Affinity's side (V2 search, beta)
|
|
166
|
+
page = client.companies.find(
|
|
167
|
+
all_of(
|
|
168
|
+
Condition("field-498220", "is-any-of", [3, 4]),
|
|
169
|
+
Condition("affinity-data-last-funding-date", "is-after", date(2025, 1, 1)),
|
|
170
|
+
),
|
|
171
|
+
sort=[Sort("affinity-data-total-funding-amount", "desc")],
|
|
172
|
+
limit=50,
|
|
166
173
|
)
|
|
167
174
|
|
|
168
175
|
# Iterate through all companies with automatic pagination
|
|
@@ -25,7 +25,9 @@ from ..confirm import run_destructive
|
|
|
25
25
|
from ..context import CLIContext
|
|
26
26
|
from ..csv_utils import write_csv_to_stdout
|
|
27
27
|
from ..decorators import category, destructive, progress_capable
|
|
28
|
+
from ..entity_search import COMPANY_KEYS, filtered_ls
|
|
28
29
|
from ..errors import CLIError
|
|
30
|
+
from ..list_search import SEARCH_CURSOR_PREFIX
|
|
29
31
|
from ..mcp_limits import apply_mcp_limits
|
|
30
32
|
from ..options import csv_output_options, csv_suboption_callback, output_options
|
|
31
33
|
from ..progress import ProgressManager, ProgressSettings
|
|
@@ -327,7 +329,8 @@ def _parse_field_types(values: tuple[str, ...]) -> list[FieldType] | None:
|
|
|
327
329
|
"filter_expr",
|
|
328
330
|
type=str,
|
|
329
331
|
default=None,
|
|
330
|
-
help="Filter: 'field op value'. Ops: = !=
|
|
332
|
+
help="Filter on company fields, applied by Affinity's search: 'field op value'. Ops: = != "
|
|
333
|
+
"=~ =^ =$ > < >= <= starts_word. E.g., 'Stage = \"Seed\"'. Name search: --query.",
|
|
331
334
|
)
|
|
332
335
|
@click.option(
|
|
333
336
|
"--query",
|
|
@@ -378,17 +381,6 @@ def company_ls(
|
|
|
378
381
|
"""
|
|
379
382
|
|
|
380
383
|
def fn(ctx: CLIContext, warnings: list[str]) -> CommandOutput:
|
|
381
|
-
if filter_expr is not None:
|
|
382
|
-
raise CLIError(
|
|
383
|
-
"The V2 /companies endpoint does not support server-side filtering. "
|
|
384
|
-
"The --filter flag was silently ignored in previous versions. "
|
|
385
|
-
"Use --query TERM for name/domain fuzzy search instead.",
|
|
386
|
-
exit_code=2,
|
|
387
|
-
error_type="unsupported_filter",
|
|
388
|
-
hint='Try: xaffinity company ls --query "Acme"',
|
|
389
|
-
details={"rejected_filter": str(filter_expr)},
|
|
390
|
-
)
|
|
391
|
-
|
|
392
384
|
client = ctx.get_client(warnings=warnings)
|
|
393
385
|
|
|
394
386
|
if cursor is not None and page_size is not None:
|
|
@@ -440,6 +432,32 @@ def company_ls(
|
|
|
440
432
|
[FieldId(fid) for fid in field_ids] if field_ids else None
|
|
441
433
|
)
|
|
442
434
|
|
|
435
|
+
# --filter (or a cursor from a filtered run): Affinity's search filters on its side
|
|
436
|
+
if filter_expr is not None or (cursor or "").startswith(SEARCH_CURSOR_PREFIX):
|
|
437
|
+
found, next_token = filtered_ls(
|
|
438
|
+
client.companies,
|
|
439
|
+
entity="company",
|
|
440
|
+
filter_expr=filter_expr,
|
|
441
|
+
cursor=cursor,
|
|
442
|
+
row_keys=COMPANY_KEYS,
|
|
443
|
+
row=_company_ls_row,
|
|
444
|
+
field_ids=list(field_ids or ()),
|
|
445
|
+
page_size=page_size,
|
|
446
|
+
max_results=max_results,
|
|
447
|
+
all_pages=all_pages,
|
|
448
|
+
warnings=warnings,
|
|
449
|
+
)
|
|
450
|
+
return CommandOutput(
|
|
451
|
+
data={"companies": found},
|
|
452
|
+
context=cmd_context,
|
|
453
|
+
pagination=(
|
|
454
|
+
{"companies": {"nextCursor": next_token, "prevCursor": None}}
|
|
455
|
+
if next_token
|
|
456
|
+
else None
|
|
457
|
+
),
|
|
458
|
+
api_called=True,
|
|
459
|
+
)
|
|
460
|
+
|
|
443
461
|
rows: list[dict[str, object]] = []
|
|
444
462
|
first_page = True
|
|
445
463
|
use_v1_search = query is not None
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"""`company duplicates`, `person duplicates`, `company connections` (V2, beta)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from affinity.models.discovery import (
|
|
8
|
+
CompanyDuplicateSuggestion,
|
|
9
|
+
CoworkerConnectionGroup,
|
|
10
|
+
DuplicateCompanyProfile,
|
|
11
|
+
InvestorExecutiveConnectionGroup,
|
|
12
|
+
PersonDuplicateSuggestion,
|
|
13
|
+
)
|
|
14
|
+
from affinity.models.entities import Person
|
|
15
|
+
from affinity.models.relationships_v2 import RelationshipPerson
|
|
16
|
+
|
|
17
|
+
from ..click_compat import RichCommand, click
|
|
18
|
+
from ..context import CLIContext
|
|
19
|
+
from ..decorators import category
|
|
20
|
+
from ..mcp_limits import apply_mcp_limits
|
|
21
|
+
from ..options import output_options
|
|
22
|
+
from ..results import CommandContext
|
|
23
|
+
from ..runner import CommandOutput, run_command
|
|
24
|
+
from ._org_reads import collect_pages, page_limit, pagination
|
|
25
|
+
from .company_cmds import _resolve_company_selector, company_group
|
|
26
|
+
from .org_read_cmds import _cursor_alone, _paging_options
|
|
27
|
+
from .person_cmds import person_group
|
|
28
|
+
|
|
29
|
+
_ORDER = click.Choice(["name", "-name", "createdAt", "-createdAt"])
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _name(first: str | None, last: str | None) -> str | None:
|
|
33
|
+
return f"{first or ''} {last or ''}".strip() or None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _company(c: DuplicateCompanyProfile) -> dict[str, object]:
|
|
37
|
+
return {"id": int(c.id), "name": c.name, "domain": c.domain}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _person(p: Person) -> dict[str, object]:
|
|
41
|
+
return {"id": int(p.id), "name": _name(p.first_name, p.last_name), "email": p.primary_email}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def company_suggestion_row(s: CompanyDuplicateSuggestion) -> dict[str, object]:
|
|
45
|
+
return {
|
|
46
|
+
"suggestionId": s.id,
|
|
47
|
+
"matchCriteria": s.match_criteria,
|
|
48
|
+
"primary": _company(s.primary),
|
|
49
|
+
"duplicate": _company(s.duplicates[0]) if s.duplicates else None,
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def person_suggestion_row(s: PersonDuplicateSuggestion) -> dict[str, object]:
|
|
54
|
+
return {
|
|
55
|
+
"suggestionId": s.id,
|
|
56
|
+
"matchCriteria": s.match_criteria,
|
|
57
|
+
"primary": _person(s.primary),
|
|
58
|
+
"duplicate": _person(s.duplicates[0]) if s.duplicates else None,
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _source(p: RelationshipPerson) -> dict[str, object]:
|
|
63
|
+
return {
|
|
64
|
+
"personId": int(p.id),
|
|
65
|
+
"name": _name(p.first_name, p.last_name),
|
|
66
|
+
"email": p.primary_email_address,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def connection_row(
|
|
71
|
+
g: CoworkerConnectionGroup | InvestorExecutiveConnectionGroup,
|
|
72
|
+
) -> dict[str, object]:
|
|
73
|
+
target = {
|
|
74
|
+
"name": g.target.full_name,
|
|
75
|
+
"title": g.target.title,
|
|
76
|
+
"linkedinUrl": g.target.linkedin_url,
|
|
77
|
+
"companyId": int(g.target.current_company.id),
|
|
78
|
+
}
|
|
79
|
+
via: list[dict[str, object]] = []
|
|
80
|
+
if isinstance(g, CoworkerConnectionGroup):
|
|
81
|
+
for c in g.connections:
|
|
82
|
+
via.append(
|
|
83
|
+
{
|
|
84
|
+
**_source(c.source),
|
|
85
|
+
"sharedEmployer": c.shared_employer.name,
|
|
86
|
+
"from": c.overlap_start.isoformat(),
|
|
87
|
+
"to": c.overlap_end.isoformat(),
|
|
88
|
+
}
|
|
89
|
+
)
|
|
90
|
+
else:
|
|
91
|
+
for deal in g.connections:
|
|
92
|
+
via.append(
|
|
93
|
+
{
|
|
94
|
+
**_source(deal.source),
|
|
95
|
+
"investorFirm": deal.investor.company.name,
|
|
96
|
+
"investorTitle": deal.investor.title,
|
|
97
|
+
"round": deal.funding_round.series,
|
|
98
|
+
"roundDate": deal.funding_round.date.isoformat(),
|
|
99
|
+
"executiveTitle": deal.executive.title,
|
|
100
|
+
"portfolioCompany": deal.executive.company.name,
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
return {"target": target, "via": via}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _duplicates_command(entity: str, parent: Any, matches: list[str]) -> None:
|
|
107
|
+
command = f"{entity} duplicates"
|
|
108
|
+
service_name = "companies" if entity == "company" else "persons"
|
|
109
|
+
row = company_suggestion_row if entity == "company" else person_suggestion_row
|
|
110
|
+
|
|
111
|
+
@category("read")
|
|
112
|
+
@parent.command(name="duplicates", cls=RichCommand)
|
|
113
|
+
@click.option("--term", default=None, help="Narrow by name (2+ characters).")
|
|
114
|
+
@click.option(
|
|
115
|
+
"--match", "match", type=click.Choice(matches), default=None, help="Match criterion."
|
|
116
|
+
)
|
|
117
|
+
@click.option("--sort", type=_ORDER, default=None, help="Order ('-' for descending).")
|
|
118
|
+
@_paging_options
|
|
119
|
+
@output_options
|
|
120
|
+
@click.pass_obj
|
|
121
|
+
@apply_mcp_limits()
|
|
122
|
+
def duplicates(
|
|
123
|
+
ctx: CLIContext,
|
|
124
|
+
*,
|
|
125
|
+
term: str | None,
|
|
126
|
+
match: str | None,
|
|
127
|
+
sort: str | None,
|
|
128
|
+
cursor: str | None,
|
|
129
|
+
max_results: int | None,
|
|
130
|
+
all_pages: bool,
|
|
131
|
+
) -> None:
|
|
132
|
+
def fn(ctx: CLIContext, warnings: list[str]) -> CommandOutput:
|
|
133
|
+
_cursor_alone(cursor, term=term, match=match, sort=sort)
|
|
134
|
+
service = getattr(ctx.get_client(warnings=warnings), service_name)
|
|
135
|
+
rows, next_cursor = collect_pages(
|
|
136
|
+
(lambda: service.list_duplicate_suggestions(cursor=cursor))
|
|
137
|
+
if cursor is not None
|
|
138
|
+
else (
|
|
139
|
+
lambda: service.list_duplicate_suggestions(
|
|
140
|
+
term=term,
|
|
141
|
+
match_criteria=match,
|
|
142
|
+
order_by=sort,
|
|
143
|
+
limit=page_limit(max_results),
|
|
144
|
+
)
|
|
145
|
+
),
|
|
146
|
+
lambda c: service.list_duplicate_suggestions(cursor=c),
|
|
147
|
+
row,
|
|
148
|
+
max_results=max_results,
|
|
149
|
+
all_pages=all_pages,
|
|
150
|
+
warnings=warnings,
|
|
151
|
+
)
|
|
152
|
+
modifiers = {k: v for k, v in (("term", term), ("match", match), ("sort", sort)) if v}
|
|
153
|
+
return CommandOutput(
|
|
154
|
+
data={"suggestions": rows},
|
|
155
|
+
context=CommandContext(name=command, inputs={}, modifiers=modifiers),
|
|
156
|
+
pagination=pagination(next_cursor),
|
|
157
|
+
api_called=True,
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
run_command(ctx, command=command, fn=fn)
|
|
161
|
+
|
|
162
|
+
confidence = (
|
|
163
|
+
"domain-match (high), domain-redirect (medium), name (low)"
|
|
164
|
+
if entity == "company"
|
|
165
|
+
else "intelligent (medium: email matching across sources), name (low)"
|
|
166
|
+
)
|
|
167
|
+
duplicates.help = (
|
|
168
|
+
f"{entity.capitalize()} pairs Affinity thinks are duplicates, not yet acted on (V2, "
|
|
169
|
+
f"beta; API 2026-07-15+). Match criteria: {confidence}. Merge one with "
|
|
170
|
+
f"`{entity} merge <primary> <duplicate>`."
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
_duplicates_command("company", company_group, ["domain-match", "domain-redirect", "name"])
|
|
175
|
+
_duplicates_command("person", person_group, ["intelligent", "name"])
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@category("read")
|
|
179
|
+
@company_group.command(name="connections", cls=RichCommand)
|
|
180
|
+
@click.argument("selector", type=str)
|
|
181
|
+
@click.option(
|
|
182
|
+
"--type",
|
|
183
|
+
"kind",
|
|
184
|
+
type=click.Choice(["coworkers", "investor-executive"]),
|
|
185
|
+
default="coworkers",
|
|
186
|
+
show_default=True,
|
|
187
|
+
help="coworkers: worked together before; investor-executive: an investor you know backed "
|
|
188
|
+
"a company the target ran.",
|
|
189
|
+
)
|
|
190
|
+
@_paging_options
|
|
191
|
+
@output_options
|
|
192
|
+
@click.pass_obj
|
|
193
|
+
@apply_mcp_limits()
|
|
194
|
+
def company_connections(
|
|
195
|
+
ctx: CLIContext,
|
|
196
|
+
*,
|
|
197
|
+
selector: str,
|
|
198
|
+
kind: str,
|
|
199
|
+
cursor: str | None,
|
|
200
|
+
max_results: int | None,
|
|
201
|
+
all_pages: bool,
|
|
202
|
+
) -> None:
|
|
203
|
+
"""Warm intros into a company: people there today whom someone you know may know (V2, beta).
|
|
204
|
+
|
|
205
|
+
One row per target, strongest first, with `via`: the people you know and why. Targets
|
|
206
|
+
aren't in your Affinity data (name, title, LinkedIn only).
|
|
207
|
+
"""
|
|
208
|
+
|
|
209
|
+
def fn(ctx: CLIContext, warnings: list[str]) -> CommandOutput:
|
|
210
|
+
_cursor_alone(cursor)
|
|
211
|
+
client = ctx.get_client(warnings=warnings)
|
|
212
|
+
company_id, resolved = _resolve_company_selector(
|
|
213
|
+
client=client, selector=selector, cache=ctx.session_cache
|
|
214
|
+
)
|
|
215
|
+
method = (
|
|
216
|
+
client.companies.list_coworker_connections
|
|
217
|
+
if kind == "coworkers"
|
|
218
|
+
else client.companies.list_investor_executive_connections
|
|
219
|
+
)
|
|
220
|
+
limit = min(max_results, 50) if max_results is not None else None
|
|
221
|
+
rows, next_cursor = collect_pages(
|
|
222
|
+
(lambda: method(company_id, cursor=cursor))
|
|
223
|
+
if cursor is not None
|
|
224
|
+
else (lambda: method(company_id, limit=limit)),
|
|
225
|
+
lambda c: method(company_id, cursor=c),
|
|
226
|
+
connection_row,
|
|
227
|
+
max_results=max_results,
|
|
228
|
+
all_pages=all_pages,
|
|
229
|
+
warnings=warnings,
|
|
230
|
+
)
|
|
231
|
+
return CommandOutput(
|
|
232
|
+
data={"connections": rows},
|
|
233
|
+
context=CommandContext(
|
|
234
|
+
name="company connections",
|
|
235
|
+
inputs={"selector": selector},
|
|
236
|
+
modifiers={"type": kind},
|
|
237
|
+
),
|
|
238
|
+
resolved=resolved,
|
|
239
|
+
pagination=pagination(next_cursor),
|
|
240
|
+
api_called=True,
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
run_command(ctx, command="company connections", fn=fn)
|