affinity-sdk 2.0.0__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.0 → affinity_sdk-2.0.2}/CHANGELOG.md +134 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/PKG-INFO +14 -7
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/README.md +13 -6
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/_entity_files_read.py +5 -8
- {affinity_sdk-2.0.0 → 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.0 → affinity_sdk-2.0.2}/affinity/cli/commands/list_cmds.py +152 -27
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/note_cmds.py +3 -2
- affinity_sdk-2.0.2/affinity/cli/commands/org_cmds.py +373 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/org_read_cmds.py +3 -3
- {affinity_sdk-2.0.0 → 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.0 → affinity_sdk-2.0.2}/affinity/cli/main.py +9 -0
- {affinity_sdk-2.0.0 → 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.0 → affinity_sdk-2.0.2}/affinity/cli/query/filters.py +1 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/query/models.py +1 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/query/parser.py +35 -6
- {affinity_sdk-2.0.0 → 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.0 → affinity_sdk-2.0.2}/affinity/client.py +56 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/clients/http.py +54 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/compare.py +47 -28
- affinity_sdk-2.0.2/affinity/criteria.py +421 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/filters.py +2 -1
- {affinity_sdk-2.0.0 → 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.0 → affinity_sdk-2.0.2}/affinity/models/secondary.py +5 -5
- {affinity_sdk-2.0.0 → 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.0 → 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.0 → affinity_sdk-2.0.2}/affinity/services/companies.py +32 -2
- {affinity_sdk-2.0.0 → 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.0 → affinity_sdk-2.0.2}/affinity/services/persons.py +27 -2
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/services/v1_only.py +264 -101
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/cli/commands.md +115 -10
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/cli/index.md +1 -1
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/examples.md +1 -1
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/api-versions-and-routing.md +2 -1
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/claude-code-plugins.md +5 -5
- {affinity_sdk-2.0.0 → 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.0 → affinity_sdk-2.0.2}/docs/public/guides/migrating-to-2.md +26 -5
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/query-command.md +92 -21
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/reference/api-coverage.md +34 -34
- affinity_sdk-2.0.2/docs/public/reference/filters.md +21 -0
- {affinity_sdk-2.0.0 → 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.0 → 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.2/docs/public/reference/services/v1/files.md +8 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/reference/services/v1/notes.md +1 -1
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.claude-plugin/plugin.json +1 -1
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.claude-plugin/skills/affinity-mcp-workflows/SKILL.md +2 -2
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.claude-plugin/skills/query-language/SKILL.md +43 -21
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.claude-plugin/skills/query-language/references/filter-operators.md +13 -5
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.claude-plugin/skills/query-language/references/quantifiers.md +25 -17
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.gitignore +3 -0
- affinity_sdk-2.0.2/mcp/.mcp-bash/VERSION +1 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/bin/mcp-bash +59 -3
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/resources.sh +2 -2
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/tools.sh +0 -1
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/cli/common.sh +2 -2
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/completion.sh +1 -1
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/core.sh +128 -7
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/elicitation.sh +19 -2
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/file_read.sh +57 -17
- {affinity_sdk-2.0.0 → 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.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/policy.sh +7 -2
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/progress-passthrough.sh +0 -2
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/progress.sh +4 -3
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/prompts.sh +3 -4
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/registry.sh +34 -7
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/resource_match.sh +18 -3
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/resources.sh +266 -44
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/runtime.sh +58 -5
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/tools.sh +64 -100
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/ui.sh +2 -1
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/validate.sh +10 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/providers/file.sh +12 -1
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/providers/ui.sh +5 -1
- {affinity_sdk-2.0.0 → 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.0 → affinity_sdk-2.0.2}/mcp/.registry/commands.generated.json +516 -10
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.registry/mcp-commands.json +47 -4
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/CHANGELOG.md +32 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/COMPATIBILITY +14 -2
- affinity_sdk-2.0.2/mcp/VERSION +1 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/mcp-bash.lock +2 -2
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/data-model/data-model.md +24 -19
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/server.d/requirements.json +1 -1
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/server.d/server.meta.json +1 -1
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/tools/execute-read-command/tool.meta.json +1 -1
- {affinity_sdk-2.0.0 → 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.0 → affinity_sdk-2.0.2}/mkdocs.yml +1 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/plugins/affinity-sdk/.claude-plugin/plugin.json +1 -1
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/plugins/affinity-sdk/.claude-plugin/skills/affinity-python-sdk/SKILL.md +42 -3
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/plugins/affinity-sdk/.claude-plugin/skills/affinity-python-sdk/references/services.md +3 -3
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/.claude-plugin/plugin.json +1 -1
- {affinity_sdk-2.0.0 → 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.0 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/query-guide.md +65 -16
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/pyproject.toml +1 -1
- {affinity_sdk-2.0.0 → 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.0 → affinity_sdk-2.0.2}/tests/test_cli_file_url.py +7 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_files_read.py +20 -20
- 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.0 → affinity_sdk-2.0.2}/tests/test_cli_person_cmds_coverage.py +4 -3
- {affinity_sdk-2.0.0 → 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.0 → 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_files_v2.py +172 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_notes_v2.py +5 -5
- 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.0 → affinity_sdk-2.0.2}/tests/test_services_v1_only_async.py +0 -2
- 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.0 → affinity_sdk-2.0.2}/tests/test_v1_only_services_additional_coverage.py +0 -2
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/api_coverage.json +58 -57
- affinity_sdk-2.0.2/tools/search_golden.py +198 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/validate_openapi_models.py +31 -0
- affinity_sdk-2.0.0/docs/public/guides/filtering.md +0 -303
- affinity_sdk-2.0.0/docs/public/reference/filters.md +0 -3
- affinity_sdk-2.0.0/docs/public/reference/services/companies.md +0 -45
- affinity_sdk-2.0.0/docs/public/reference/services/lists.md +0 -5
- affinity_sdk-2.0.0/docs/public/reference/services/v1/files.md +0 -8
- affinity_sdk-2.0.0/mcp/.mcp-bash/VERSION +0 -1
- affinity_sdk-2.0.0/mcp/.mcp-bash/lib/lock.sh +0 -176
- affinity_sdk-2.0.0/mcp/.mcp-bash/vendor.json +0 -1
- affinity_sdk-2.0.0/mcp/VERSION +0 -1
- affinity_sdk-2.0.0/mcp/tools/query/tool.meta.json +0 -111
- affinity_sdk-2.0.0/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/filtering.md +0 -51
- affinity_sdk-2.0.0/tests/test_files_v2.py +0 -111
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.claude-plugin/marketplace.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.cursor/rules/test-data-privacy.mdc +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.editorconfig +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.env.example +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.gitattributes +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/CODEOWNERS +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/PULL_REQUEST_TEMPLATE/cli_command.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/PULL_REQUEST_TEMPLATE/release.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/dependabot.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/labels.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/mcp-release-install-footer.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/pull_request_template.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/release-install-footer.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/workflows/ci.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/workflows/cowork-replay.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/workflows/docs.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/workflows/labels.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/workflows/linkcheck.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/workflows/openapi-validation.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/workflows/plugin-build.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/workflows/plugin-release.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/workflows/release-detect.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/workflows/release.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.github/workflows/version-check.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.gitignore +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/.pre-commit-config.yaml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/AGENTS.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/CODE_OF_CONDUCT.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/CONTRIBUTING.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/LICENSE +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/SECURITY.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/VERSIONING.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/__init__.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/_internal/__init__.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/_internal/keyfile.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/api_versions.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/__init__.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/__main__.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/_update_worker.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/click_compat.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/__init__.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/_entity_field.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/_entity_files_dump.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/_entity_files_upload.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/_list_entry_fields.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/_org_reads.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/_search_common.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/_v1_parsing.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/completion_cmd.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/config_cmds.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/entry_cmds.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/field_cmds.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/file_cmds.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/file_url_cmd.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/interaction_cmds.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/opportunity_cmds.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/query_cmd.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/relationship_strength_cmds.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/reminder_cmds.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/resolve_url_cmd.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/session_cmds.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/task_cmds.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/transcript_cmds.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/version_cmd.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/webhook_cmds.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/commands/whoami_cmd.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/config.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/confirm.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/constants.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/context.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/csv_utils.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/date_utils.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/decorators.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/errors.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/field_utils.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/formatters.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/help_json.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/interaction_utils.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/logging.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/mcp_limits.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/options.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/paths.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/progress.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/query/__init__.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/query/aggregates.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/query/cursor.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/query/dates.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/query/exceptions.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/query/output.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/query/progress.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/query/schema.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/render.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/resolve.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/resolvers.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/results.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/runner.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/serialization.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/session_cache.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/types.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/cli/update_check.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/clients/__init__.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/clients/pipeline.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/downloads.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/exceptions.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/field_resolve_utils.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/field_resolver.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/hooks.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/inbound_webhooks.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/models/entities.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/models/interactions_v2.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/models/pagination.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/models/rate_limit_snapshot.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/models/relationships_v2.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/models/search.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/models/transcripts.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/models/types.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/policies.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/progress.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/py.typed +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/services/_dropdown_options.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/services/_field_listing.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/services/_field_updates.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/services/_note_html.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/services/_v2_filters.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/services/opportunities.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/services/rate_limits.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/services/reminders.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/services/search.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/services/tasks.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/services/transcripts.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/services/webhooks.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/affinity/types.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/codecov.yml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/cli-development-guide.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/ai-integrations/index.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/changelog.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/cli/scripting.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/cli-reference.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/getting-started.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/glossary.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/affinity-official-mcp-comparison.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/api-versions.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/authentication.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/configuration.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/datetime-handling.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/debugging-hooks.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/errors-and-retries.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/field-types-and-values.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/field-values.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/ids-and-types.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/models.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/opportunity-associations.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/pagination.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/performance.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/rate-limits.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/sync-vs-async.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/guides/webhooks.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/index.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/mcp/index.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/reference/client.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/reference/exceptions.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/reference/models.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/reference/services/opportunities.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/reference/services/reminders.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/reference/services/tasks.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/reference/services/v1/auth.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/reference/services/v1/field-values.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/reference/services/v1/fields.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/reference/services/v1/interactions.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/reference/services/v1/relationships.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/reference/services/webhooks.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/reference/types.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/docs/public/troubleshooting.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/examples/advanced_usage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/examples/async_lifecycle.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/examples/basic_usage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/examples/filter_builder.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/examples/hooks_debugging.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/examples/list_management.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/examples/resolve_helpers.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/examples/task_polling.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.claude-plugin/.gitignore +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.claude-plugin/skills/pipeline-history/SKILL.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.claude-plugin/skills/query-language/references/include-expand.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.claude-plugin/skills/query-language/references/output-formats.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.claude-plugin/xaffinity-mcp.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/completion.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/lifecycle.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/logging.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/ping.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/prompts.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/handlers/roots.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/auth.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/capabilities.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/cli/health.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/handler_helpers.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/hash.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/ids.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/json.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/logging.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/meta_env.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/paginate.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/path.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/require.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/resource_content.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/resource_providers.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/roots.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/rpc.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/spec.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/timeout.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/tools_policy.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/ui-templates.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/lib/uri.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/providers/echo.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/providers/git.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/providers/https.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/sdk/tool-error.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.mcp-bash/sdk/ui-sdk.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.registry/prompts.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.registry/resource-templates.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.registry/resources.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/.registry/ui-resources.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/Makefile +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/README.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/completions/entity-name.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/completions/list-name.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/completions/status-value.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/docs/DEBUGGING.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/icon.svg +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/lib/cache.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/lib/cli-detect.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/lib/cli-gateway.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/lib/common.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/lib/entity-types.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/lib/field-resolution.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/mcp-publisher.lock +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/mcpb.conf +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/change-status/change-status.completion.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/change-status/change-status.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/change-status/change-status.txt +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/interaction-brief/interaction-brief.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/interaction-brief/interaction-brief.txt +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/log-call/log-call.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/log-call/log-call.txt +0 -0
- {affinity_sdk-2.0.0 → 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.0 → affinity_sdk-2.0.2}/mcp/prompts/log-interaction-and-update-workflow/log-interaction-and-update-workflow.txt +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/log-message/log-message.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/log-message/log-message.txt +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/pipeline-review/pipeline-review.completion.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/pipeline-review/pipeline-review.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/pipeline-review/pipeline-review.txt +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/prepare-briefing/prepare-briefing.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/prepare-briefing/prepare-briefing.txt +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/warm-intro/warm-intro.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/prompts/warm-intro/warm-intro.txt +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/providers/xaffinity.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/data-model/data-model.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/field-catalogs/field-catalogs.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/field-catalogs/field-catalogs.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/interaction-enums/interaction-enums.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/interaction-enums/interaction-enums.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/me/me.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/me/me.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/me-person-id/me-person-id.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/me-person-id/me-person-id.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/query-guide/query-guide.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/query-guide/query-guide.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/saved-views/saved-views.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/saved-views/saved-views.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/workflow-config/workflow-config.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/workflow-config/workflow-config.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/workflows-guide/workflows-guide.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/workflows-guide/workflows-guide.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/xaffinity-field-catalogs.completion.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/xaffinity-saved-views.completion.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/resources/xaffinity-workflow-config.completion.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/server.d/env.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/server.d/health-checks.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/server.d/policy.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/server.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/test/README.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/test/run.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/test/test_env_update_check.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/test-progress.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/tools/discover-commands/tool.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/tools/discover-commands/tool.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/tools/execute-read-command/tool.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/tools/execute-write-command/tool.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/tools/get-entity-dossier/tool.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/tools/get-entity-dossier/tool.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/tools/get-file-url/tool.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/tools/get-file-url/tool.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/tools/query/tool.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/tools/read-xaffinity-resource/tool.meta.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/tools/read-xaffinity-resource/tool.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/user-config.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/xaffinity-mcp-env.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/mcp/xaffinity-mcp.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/hooks/guard-env-read.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/hooks/hooks.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/hooks/pre-xaffinity.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/hooks/session-setup.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/files-and-writes.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/history-and-activity.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/interactions.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/setup.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cli/query/test_cursor.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cli/test_company_create_dedup.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cli/test_company_ls_filter_rejection.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cli/test_formatters.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cli/test_output_formats_integration.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cli/test_person_create_dedup.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cli/test_person_ls_filter_rejection.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cli/test_query_filter_rejection.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cli/test_query_list_entry_relationships.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cli/test_query_list_export_parity.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cli/test_query_output_flattening.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cli/test_query_output_truncation.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cli/test_query_unreplied.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/conftest.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/.cowork-redact.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/README.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/cassettes/company-lists-status.cassette.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/cassettes/hook-blocks-without-key.cassette.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/cassettes/no-key-skill-path.cassette.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/cassettes/status-history.cassette.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/fixtures/workdir-key/README.txt +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/fixtures/workdir-key/xaffinity-test-key +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/fixtures/workdir-nokey/README.txt +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/image/Dockerfile +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/image/fakeaff/build_fixtures.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/image/fakeaff/fixtures.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/image/fakeaff/server.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/image/xaffinity-wrapper.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/privacy-allow.txt +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/record.sh +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/scenarios/company-lists-status.yaml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/scenarios/hook-blocks-without-key.yaml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/scenarios/no-key-skill-path.yaml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/scenarios/status-history.yaml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/sessions/no-key.yaml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/cowork/sessions/with-key.yaml +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/field_write_mocks.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/fixtures/openapi/mini_openapi.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/fixtures/webhooks/field_value_updated.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/fixtures/webhooks/list_entry_created.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/fixtures/webhooks/organization_created.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/fixtures/webhooks/organization_merged.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/fixtures/webhooks/person_created.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/fixtures/webhooks/unknown_event.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/integration/README.md +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/integration/conftest.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/integration/setup_query_parity_data.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/integration/test_cli_writes.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/integration/test_query_parity_integration.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/integration/test_sdk_reads.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/integration/test_sdk_writes.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/integration/test_sdk_writes_runner.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/mcp/__init__.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/mcp/test_query_cursor.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/skill-evals/xaffinity-cli-usage-evals/evals.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/spec_guard.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_affinity_client_wrapper_additional_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_api_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_api_key_file_formats.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_api_key_resolution.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_api_version.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_api_version_per_operation.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_async_file_download_streaming.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_batch_get.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_api_version.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_column_limiting.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_command_context.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_company_get.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_config_cmds.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_context_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_csv_export.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_date_params.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_date_utils.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_datetime_formatting.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_datetime_header_offsets.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_domain_linkification.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_dotenv_resolution.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_dropdown_field_writes.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_enriched_field_writes.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_entity_field_writes.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_entity_files_dump.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_entry_field.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_entry_field_batch_writes.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_entry_field_multi_value_limits.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_error_hints.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_error_rendering.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_field_history.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_field_history_bulk.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_field_options_and_transcripts.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_field_utils.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_field_utils_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_field_utils_set_phase.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_field_value_humanization.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_files_ls.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_get_interaction_dates.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_help_json.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_interaction_date_chunking.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_interaction_utils.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_json_safety.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_list_cmds_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_list_expand_interactions.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_list_export_entity_scope.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_list_export_field_refresh.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_list_export_filter_safety.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_list_export_truncation_meta.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_missing_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_multi_value_truncation_warnings.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_no_network_commands.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_notes_writes.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_opportunity_cmds.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_opportunity_cmds_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_pager_logic.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_person_get.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_plugin_manifest.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_pre_xaffinity_hook.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_progress_manager.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_query_aggregates.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_query_cmd.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_query_cmd_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_query_dates.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_query_executor.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_query_expand_interactions.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_query_filters.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_query_integration.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_query_parser.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_query_safety.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_query_schema.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_rate_limit_rendering.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_rate_limit_throttle.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_reminders.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_render_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_resolve_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_resolve_url_parsing.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_result_summary.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_safe_field_writes.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_search.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_serialization.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_session_cache.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_session_setup_hook.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_set_phase_atomicity.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_types.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_unreplied.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_update_check.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_v1_only_cmds.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_v1_parsing.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_webhooks.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_cli_write_ops.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_client.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_companies_create_dedup.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_companies_filter_rejection.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_env_helpers.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_exceptions_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_field_resolver.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_field_service_caching.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_field_types_c4.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_field_value_type.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_field_values_get_value.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_file_batch_get.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_file_download_streaming.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_file_list_batch.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_file_upload_helpers_and_validation.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_files_upload_returning_files.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_filters.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_generate_mcp_command_registry.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_get_fields_filter_includes.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_get_fields_pagination.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_get_first.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_hidden_field_values.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_hooks.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_http_client_additional_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_http_client_remaining_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_inbound_webhooks.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_integration_smoke.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_interaction_date_validation.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_interactions_and_files_regressions.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_isodatetime.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_list_entry_membership_and_opportunities.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_list_term.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_lists_v2_writes.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_mcp_bundle_env_and_completions.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_mcp_cli_version_check.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_mcp_entity_dossier.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_mcp_gateway_limits.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_mcp_history_bulk_gateway.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_mcp_limits.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_mcp_query_cli_error.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_mcp_read_truncation.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_mcp_resource_scripts.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_models.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_models_v2_2026_fields.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_multi_value_limits.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_new_features.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_notes_v2_writes.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_opportunities_filter_rejection.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_org_reads.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_pagination_iterators.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_persons_create_dedup.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_persons_filter_rejection.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_public_api.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_rate_limit_v2.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_raw_pipeline_hook_events.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_readonly_factory.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_reminder_list_batch.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_reminders_v2.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_requirements_additional.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_sdk_interaction_dates.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_search.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_service_get_parameter_combinations.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_services_companies_coverage_gaps.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_services_dropdown_options.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_services_entity_field_updates.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_services_field_value_changes.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_services_list_entries_filter_paths.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_services_lists_additional_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_services_lists_coverage_gaps.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_services_opportunities_additional_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_services_opportunities_coverage_gaps.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_services_opportunities_tasks_additional_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_services_persons_companies_additional_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_services_rate_limits_coverage_gaps.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_services_v1_only_coverage_gaps.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_small_modules_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_spec_guard.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_transport_and_readonly_mode.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_v1_association_parsing.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_v1_only_services_more_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_v2_request_bodies.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_validate_openapi_tool.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/test_webhooks_v2.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/unit/__init__.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tests/unit/test_exceptions.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/__init__.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/api_coverage.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/api_coverage_v1_snapshot.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/check_cli_patterns.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/generate_mcp_command_registry.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/generate_release_notes.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/generate_requirements_mapping.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/openapi_snapshots/2024-01-01.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/openapi_snapshots/2026-07-15.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/openapi_snapshots/2026-09-17.json +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/sync_mcp_bundle_env.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/sync_mcp_registry.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/sync_mcp_version.py +0 -0
- {affinity_sdk-2.0.0 → affinity_sdk-2.0.2}/tools/validate_mcp_registry_metadata.py +0 -0
|
@@ -7,6 +7,140 @@ 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
|
+
|
|
114
|
+
## [2.0.1] - 2026-10-12
|
|
115
|
+
|
|
116
|
+
### Changed (breaking)
|
|
117
|
+
|
|
118
|
+
**Exception to semantic versioning:** these renames break code written against 2.0.0, in a
|
|
119
|
+
patch release. 2.0.0 had been out for under an hour, and the renames remove method names that
|
|
120
|
+
said which Affinity API they used instead of what they do.
|
|
121
|
+
|
|
122
|
+
- `notes.list_v2()` / `iter_v2()` → **`notes.feed()` / `iter_feed()`** (every note across the
|
|
123
|
+
organization; the CLI's `note feed`).
|
|
124
|
+
- `notes.get_v2()` → **`notes.get()`**, which now returns `NoteV2` (`includes=True` adds the
|
|
125
|
+
attached companies, persons and opportunities). The V1 `notes.get()` (returning `Note`) is
|
|
126
|
+
removed; `notes.list()` (one entity's notes, V1) is unchanged.
|
|
127
|
+
- `files.list_v2()` / `iter_v2()` → **`files.feed()` / `iter_feed()`** (every file you can see,
|
|
128
|
+
newest first).
|
|
129
|
+
- `files.get_v2()` is removed. **`files.get_download_url()`** now asks V2 first: one request
|
|
130
|
+
for the details and a signed URL (valid 60 seconds) instead of V1's two. It falls back to
|
|
131
|
+
V1 when the client is pinned to an API version older than 2026-09-17, or when V2 refuses or
|
|
132
|
+
doesn't find the file; the result (`PresignedUrl`) is the same either way. `files.get()`
|
|
133
|
+
stays on V1 (`EntityFile`, with the file's person, company or opportunity) and works under
|
|
134
|
+
any version pin.
|
|
135
|
+
- CLI `note get` reads the note from V2: same output keys, `content` is the stored HTML (as in
|
|
136
|
+
`note create`/`update` output), and the attachment ids come from V2.
|
|
137
|
+
- CLI `files read` and `file-url` get the file's details and URL in one request where V2 can
|
|
138
|
+
answer (V1's path otherwise).
|
|
139
|
+
|
|
140
|
+
### Plugins
|
|
141
|
+
|
|
142
|
+
- **SDK plugin**: 2.0.0 → 2.0.1 — skill: the renamed note methods.
|
|
143
|
+
|
|
10
144
|
## [2.0.0] - 2026-10-12
|
|
11
145
|
|
|
12
146
|
### Highlights
|
|
@@ -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
|
|
@@ -87,9 +87,9 @@ def read_file_content(
|
|
|
87
87
|
def fn(ctx: CLIContext, warnings: list[str]) -> CommandOutput:
|
|
88
88
|
client = ctx.get_client(warnings=warnings)
|
|
89
89
|
|
|
90
|
-
#
|
|
91
|
-
|
|
92
|
-
file_size =
|
|
90
|
+
# Name, size, type and a signed URL: one V2 request (or V1's two where V2 can't answer)
|
|
91
|
+
presigned = client.files.get_download_url(FileId(file_id))
|
|
92
|
+
file_size = presigned.size or 0
|
|
93
93
|
|
|
94
94
|
# Validate offset
|
|
95
95
|
if offset < 0:
|
|
@@ -107,9 +107,6 @@ def read_file_content(
|
|
|
107
107
|
hint=f"File size is {file_size} bytes. Use --offset 0 to start from beginning.",
|
|
108
108
|
)
|
|
109
109
|
|
|
110
|
-
# Get presigned URL
|
|
111
|
-
presigned = client.files.get_download_url(FileId(file_id))
|
|
112
|
-
|
|
113
110
|
# Calculate actual bytes to read
|
|
114
111
|
remaining = file_size - offset
|
|
115
112
|
bytes_to_read = min(limit, remaining)
|
|
@@ -161,9 +158,9 @@ def read_file_content(
|
|
|
161
158
|
|
|
162
159
|
data = {
|
|
163
160
|
"fileId": int(file_id),
|
|
164
|
-
"name":
|
|
161
|
+
"name": presigned.name,
|
|
165
162
|
"size": file_size,
|
|
166
|
-
"contentType":
|
|
163
|
+
"contentType": presigned.content_type,
|
|
167
164
|
"offset": offset,
|
|
168
165
|
"length": actual_length,
|
|
169
166
|
"hasMore": has_more,
|
|
@@ -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)
|