affinity-sdk 1.28.0__tar.gz → 2.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/ci.yml +3 -0
- affinity_sdk-2.0.0/.github/workflows/cowork-replay.yml +33 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/plugin-build.yml +13 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.gitignore +3 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.pre-commit-config.yaml +3 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/CHANGELOG.md +178 -4
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/PKG-INFO +23 -17
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/README.md +22 -16
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/_internal/keyfile.py +4 -2
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/config_cmds.py +15 -4
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/field_cmds.py +208 -33
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/list_cmds.py +6 -1
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/note_cmds.py +148 -29
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/reminder_cmds.py +157 -191
- affinity_sdk-2.0.0/affinity/cli/commands/webhook_cmds.py +365 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/confirm.py +12 -4
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/main.py +2 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/client.py +2 -4
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/inbound_webhooks.py +1 -1
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/__init__.py +17 -3
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/entities.py +20 -7
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/secondary.py +196 -40
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/types.py +57 -14
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/__init__.py +4 -4
- affinity_sdk-2.0.0/affinity/services/_note_html.py +165 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/_v2_filters.py +8 -1
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/lists.py +67 -63
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/rate_limits.py +12 -9
- affinity_sdk-2.0.0/affinity/services/reminders.py +715 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/v1_only.py +208 -604
- affinity_sdk-2.0.0/affinity/services/webhooks.py +304 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/types.py +2 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/cli/commands.md +93 -7
- affinity_sdk-2.0.0/docs/public/guides/api-versions-and-routing.md +80 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/authentication.md +2 -2
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/errors-and-retries.md +6 -9
- affinity_sdk-2.0.0/docs/public/guides/migrating-to-2.md +90 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/pagination.md +3 -3
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/webhooks.md +45 -8
- affinity_sdk-2.0.0/docs/public/reference/api-coverage.md +190 -0
- affinity_sdk-2.0.0/docs/public/reference/services/reminders.md +5 -0
- affinity_sdk-2.0.0/docs/public/reference/services/v1/files.md +8 -0
- affinity_sdk-2.0.0/docs/public/reference/services/v1/notes.md +6 -0
- affinity_sdk-2.0.0/docs/public/reference/services/webhooks.md +5 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/plugin.json +1 -1
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/skills/pipeline-history/SKILL.md +8 -6
- affinity_sdk-2.0.0/mcp/.mcp-bash/VERSION +1 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/bin/mcp-bash +11 -1
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/cli/common.sh +4 -10
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/core.sh +118 -8
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/elicitation.sh +3 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/runtime.sh +25 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/timeout.sh +19 -6
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/tools.sh +52 -6
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/tools_policy.sh +48 -2
- affinity_sdk-2.0.0/mcp/.mcp-bash/sdk/tool-error.sh +113 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/sdk/tool-sdk.sh +172 -15
- affinity_sdk-2.0.0/mcp/.mcp-bash/vendor.json +1 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.registry/commands.generated.json +332 -20
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.registry/mcp-commands.json +29 -1
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/CHANGELOG.md +52 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/COMPATIBILITY +13 -2
- affinity_sdk-2.0.0/mcp/VERSION +1 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/mcp-bash.lock +2 -2
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/data-model/data-model.md +2 -1
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/server.d/policy.sh +4 -5
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/server.d/requirements.json +1 -1
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/server.d/server.meta.json +1 -1
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/test/run.sh +8 -5
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/execute-write-command/tool.meta.json +2 -2
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/execute-write-command/tool.sh +18 -2
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/query/tool.sh +1 -1
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mkdocs.yml +4 -2
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/affinity-sdk/.claude-plugin/plugin.json +1 -1
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/affinity-sdk/.claude-plugin/skills/affinity-python-sdk/SKILL.md +1 -1
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/affinity-sdk/.claude-plugin/skills/affinity-python-sdk/references/services.md +4 -1
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/.claude-plugin/plugin.json +2 -16
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/hooks/guard-env-read.sh +2 -2
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/hooks/pre-xaffinity.sh +9 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/hooks/session-setup.sh +8 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/SKILL.md +8 -3
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/history-and-activity.md +7 -2
- affinity_sdk-2.0.0/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/setup.md +76 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/pyproject.toml +1 -1
- affinity_sdk-2.0.0/tests/cowork/.cowork-redact.json +22 -0
- affinity_sdk-2.0.0/tests/cowork/README.md +54 -0
- affinity_sdk-2.0.0/tests/cowork/cassettes/company-lists-status.cassette.json +410 -0
- affinity_sdk-2.0.0/tests/cowork/cassettes/hook-blocks-without-key.cassette.json +306 -0
- affinity_sdk-2.0.0/tests/cowork/cassettes/no-key-skill-path.cassette.json +395 -0
- affinity_sdk-2.0.0/tests/cowork/cassettes/status-history.cassette.json +469 -0
- affinity_sdk-2.0.0/tests/cowork/fixtures/workdir-key/README.txt +2 -0
- affinity_sdk-2.0.0/tests/cowork/fixtures/workdir-key/xaffinity-test-key +1 -0
- affinity_sdk-2.0.0/tests/cowork/fixtures/workdir-nokey/README.txt +1 -0
- affinity_sdk-2.0.0/tests/cowork/image/Dockerfile +13 -0
- affinity_sdk-2.0.0/tests/cowork/image/fakeaff/build_fixtures.py +268 -0
- affinity_sdk-2.0.0/tests/cowork/image/fakeaff/fixtures.json +790 -0
- affinity_sdk-2.0.0/tests/cowork/image/fakeaff/server.py +72 -0
- affinity_sdk-2.0.0/tests/cowork/image/xaffinity-wrapper.sh +23 -0
- affinity_sdk-2.0.0/tests/cowork/privacy-allow.txt +7 -0
- affinity_sdk-2.0.0/tests/cowork/record.sh +50 -0
- affinity_sdk-2.0.0/tests/cowork/scenarios/company-lists-status.yaml +17 -0
- affinity_sdk-2.0.0/tests/cowork/scenarios/hook-blocks-without-key.yaml +9 -0
- affinity_sdk-2.0.0/tests/cowork/scenarios/no-key-skill-path.yaml +13 -0
- affinity_sdk-2.0.0/tests/cowork/scenarios/status-history.yaml +15 -0
- affinity_sdk-2.0.0/tests/cowork/sessions/no-key.yaml +6 -0
- affinity_sdk-2.0.0/tests/cowork/sessions/with-key.yaml +7 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/test_sdk_reads.py +8 -10
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/test_sdk_writes.py +44 -69
- affinity_sdk-2.0.0/tests/test_api_coverage.py +162 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_config_cmds.py +24 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_csv_export.py +10 -10
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_date_params.py +17 -14
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_field_history.py +63 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_field_history_bulk.py +184 -15
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_field_options_and_transcripts.py +1 -1
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_list_cmds_coverage.py +13 -13
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_list_expand_interactions.py +6 -6
- affinity_sdk-2.0.0/tests/test_cli_notes_writes.py +181 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_opportunity_cmds.py +1 -1
- affinity_sdk-2.0.0/tests/test_cli_plugin_manifest.py +23 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_pre_xaffinity_hook.py +51 -0
- affinity_sdk-2.0.0/tests/test_cli_reminders.py +253 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_session_setup_hook.py +38 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_set_phase_atomicity.py +50 -9
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_v1_only_cmds.py +0 -195
- affinity_sdk-2.0.0/tests/test_cli_webhooks.py +212 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_write_ops.py +2 -2
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_client.py +2 -2
- affinity_sdk-2.0.0/tests/test_files_v2.py +111 -0
- affinity_sdk-2.0.0/tests/test_lists_v2_writes.py +144 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_cli_version_check.py +29 -0
- affinity_sdk-2.0.0/tests/test_mcp_query_cli_error.py +75 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_models.py +1 -1
- affinity_sdk-2.0.0/tests/test_notes_v2_writes.py +300 -0
- affinity_sdk-2.0.0/tests/test_rate_limit_v2.py +78 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_readonly_factory.py +3 -2
- affinity_sdk-2.0.0/tests/test_reminder_list_batch.py +136 -0
- affinity_sdk-2.0.0/tests/test_reminders_v2.py +541 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_requirements_additional.py +4 -3
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_lists_additional_coverage.py +22 -10
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_rate_limits_coverage_gaps.py +18 -23
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_v1_only_async.py +3 -119
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_transport_and_readonly_mode.py +3 -2
- affinity_sdk-2.0.0/tests/test_v1_association_parsing.py +28 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_v1_only_services_additional_coverage.py +3 -63
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_v1_only_services_more_coverage.py +0 -133
- affinity_sdk-2.0.0/tests/test_v2_request_bodies.py +271 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_validate_openapi_tool.py +33 -0
- affinity_sdk-2.0.0/tests/test_webhooks_v2.py +232 -0
- affinity_sdk-2.0.0/tools/api_coverage.json +1155 -0
- affinity_sdk-2.0.0/tools/api_coverage.py +238 -0
- affinity_sdk-2.0.0/tools/api_coverage_v1_snapshot.json +68 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/validate_openapi_models.py +37 -4
- affinity_sdk-1.28.0/docs/public/guides/api-versions-and-routing.md +0 -52
- affinity_sdk-1.28.0/docs/public/reference/services/v1/files.md +0 -3
- affinity_sdk-1.28.0/docs/public/reference/services/v1/notes.md +0 -3
- affinity_sdk-1.28.0/docs/public/reference/services/v1/reminders.md +0 -3
- affinity_sdk-1.28.0/docs/public/reference/services/v1/webhooks.md +0 -3
- affinity_sdk-1.28.0/mcp/.mcp-bash/VERSION +0 -1
- affinity_sdk-1.28.0/mcp/.mcp-bash/vendor.json +0 -1
- affinity_sdk-1.28.0/mcp/VERSION +0 -1
- affinity_sdk-1.28.0/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/setup.md +0 -58
- affinity_sdk-1.28.0/tests/test_reminder_list_batch.py +0 -184
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.claude-plugin/marketplace.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.cursor/rules/test-data-privacy.mdc +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.editorconfig +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.env.example +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.gitattributes +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/CODEOWNERS +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/PULL_REQUEST_TEMPLATE/cli_command.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/PULL_REQUEST_TEMPLATE/release.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/dependabot.yml +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/labels.yml +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/mcp-release-install-footer.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/pull_request_template.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/release-install-footer.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/docs.yml +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/labels.yml +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/linkcheck.yml +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/openapi-validation.yml +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/plugin-release.yml +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/release-detect.yml +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/release.yml +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/version-check.yml +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/AGENTS.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/CODE_OF_CONDUCT.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/CONTRIBUTING.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/LICENSE +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/SECURITY.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/VERSIONING.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/__init__.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/_internal/__init__.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/api_versions.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/__init__.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/__main__.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/_update_worker.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/click_compat.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/__init__.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_entity_field.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_entity_files_dump.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_entity_files_read.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_entity_files_upload.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_list_entry_fields.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_org_reads.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_search_common.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_v1_parsing.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/company_cmds.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/completion_cmd.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/entry_cmds.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/file_cmds.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/file_url_cmd.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/interaction_cmds.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/opportunity_cmds.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/org_read_cmds.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/person_cmds.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/query_cmd.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/relationship_strength_cmds.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/resolve_url_cmd.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/session_cmds.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/task_cmds.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/transcript_cmds.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/version_cmd.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/whoami_cmd.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/config.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/constants.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/context.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/csv_utils.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/date_utils.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/decorators.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/errors.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/field_utils.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/formatters.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/help_json.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/interaction_utils.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/logging.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/mcp_limits.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/options.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/paths.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/progress.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/__init__.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/aggregates.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/cursor.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/dates.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/exceptions.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/executor.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/filters.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/models.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/output.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/parser.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/planner.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/progress.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/schema.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/render.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/resolve.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/resolvers.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/results.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/runner.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/serialization.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/session_cache.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/types.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/update_check.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/clients/__init__.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/clients/http.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/clients/pipeline.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/compare.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/downloads.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/exceptions.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/field_resolve_utils.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/field_resolver.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/filters.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/hooks.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/interactions_v2.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/pagination.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/rate_limit_snapshot.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/relationships_v2.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/search.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/transcripts.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/policies.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/progress.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/py.typed +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/_dropdown_options.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/_field_listing.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/_field_updates.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/_org_reads.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/companies.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/opportunities.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/persons.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/search.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/tasks.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/transcripts.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/codecov.yml +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/cli-development-guide.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/ai-integrations/index.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/changelog.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/cli/index.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/cli/scripting.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/cli-reference.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/examples.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/getting-started.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/glossary.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/affinity-official-mcp-comparison.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/api-versions.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/claude-code-plugins.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/configuration.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/csv-export.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/datetime-handling.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/debugging-hooks.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/field-types-and-values.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/field-values.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/filtering.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/ids-and-types.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/models.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/opportunity-associations.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/performance.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/query-command.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/rate-limits.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/sync-vs-async.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/index.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/mcp/index.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/client.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/exceptions.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/filters.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/models.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/query-language.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/companies.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/lists.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/opportunities.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/persons.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/tasks.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/v1/auth.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/v1/field-values.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/v1/fields.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/v1/interactions.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/v1/relationships.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/types.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/troubleshooting.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/advanced_usage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/async_lifecycle.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/basic_usage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/filter_builder.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/hooks_debugging.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/list_management.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/resolve_helpers.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/task_polling.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/.gitignore +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/skills/affinity-mcp-workflows/SKILL.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/skills/query-language/SKILL.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/skills/query-language/references/filter-operators.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/skills/query-language/references/include-expand.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/skills/query-language/references/output-formats.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/skills/query-language/references/quantifiers.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/xaffinity-mcp.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.gitignore +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/completion.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/lifecycle.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/logging.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/ping.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/prompts.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/resources.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/roots.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/tools.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/auth.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/capabilities.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/cli/health.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/completion.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/file_read.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/handler_helpers.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/hash.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/ids.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/io.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/json.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/lock.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/logging.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/meta_env.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/paginate.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/path.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/policy.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/progress-passthrough.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/progress.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/prompts.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/registry.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/require.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/resource_content.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/resource_match.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/resource_providers.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/resources.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/roots.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/rpc.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/spec.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/ui-templates.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/ui.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/uri.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/validate.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/providers/echo.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/providers/file.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/providers/git.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/providers/https.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/providers/ui.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/sdk/ui-sdk.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.registry/prompts.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.registry/resource-templates.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.registry/resources.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.registry/ui-resources.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/Makefile +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/README.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/completions/entity-name.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/completions/list-name.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/completions/status-value.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/docs/DEBUGGING.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/icon.svg +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/lib/cache.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/lib/cli-detect.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/lib/cli-gateway.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/lib/common.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/lib/entity-types.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/lib/field-resolution.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/mcp-publisher.lock +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/mcpb.conf +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/change-status/change-status.completion.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/change-status/change-status.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/change-status/change-status.txt +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/interaction-brief/interaction-brief.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/interaction-brief/interaction-brief.txt +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/log-call/log-call.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/log-call/log-call.txt +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/log-interaction-and-update-workflow/log-interaction-and-update-workflow.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/log-interaction-and-update-workflow/log-interaction-and-update-workflow.txt +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/log-message/log-message.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/log-message/log-message.txt +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/pipeline-review/pipeline-review.completion.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/pipeline-review/pipeline-review.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/pipeline-review/pipeline-review.txt +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/prepare-briefing/prepare-briefing.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/prepare-briefing/prepare-briefing.txt +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/warm-intro/warm-intro.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/warm-intro/warm-intro.txt +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/providers/xaffinity.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/data-model/data-model.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/field-catalogs/field-catalogs.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/field-catalogs/field-catalogs.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/interaction-enums/interaction-enums.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/interaction-enums/interaction-enums.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/me/me.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/me/me.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/me-person-id/me-person-id.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/me-person-id/me-person-id.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/query-guide/query-guide.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/query-guide/query-guide.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/saved-views/saved-views.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/saved-views/saved-views.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/workflow-config/workflow-config.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/workflow-config/workflow-config.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/workflows-guide/workflows-guide.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/workflows-guide/workflows-guide.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/xaffinity-field-catalogs.completion.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/xaffinity-saved-views.completion.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/xaffinity-workflow-config.completion.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/server.d/env.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/server.d/health-checks.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/server.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/test/README.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/test/test_env_update_check.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/test-progress.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/discover-commands/tool.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/discover-commands/tool.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/execute-read-command/tool.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/execute-read-command/tool.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/get-entity-dossier/tool.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/get-entity-dossier/tool.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/get-file-url/tool.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/get-file-url/tool.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/query/tool.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/read-xaffinity-resource/tool.meta.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/read-xaffinity-resource/tool.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/user-config.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/xaffinity-mcp-env.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/xaffinity-mcp.sh +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/hooks/hooks.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/files-and-writes.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/filtering.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/interactions.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/query-guide.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/query/test_cursor.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_company_create_dedup.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_company_ls_filter_rejection.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_formatters.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_output_formats_integration.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_person_create_dedup.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_person_ls_filter_rejection.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_query_filter_rejection.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_query_list_entry_relationships.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_query_list_export_parity.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_query_output_flattening.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_query_output_truncation.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_query_unreplied.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/conftest.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/field_write_mocks.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/fixtures/openapi/mini_openapi.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/fixtures/webhooks/field_value_updated.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/fixtures/webhooks/list_entry_created.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/fixtures/webhooks/organization_created.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/fixtures/webhooks/organization_merged.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/fixtures/webhooks/person_created.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/fixtures/webhooks/unknown_event.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/README.md +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/conftest.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/setup_query_parity_data.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/test_cli_writes.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/test_query_parity_integration.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/test_sdk_writes_runner.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/mcp/__init__.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/mcp/test_query_cursor.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/skill-evals/xaffinity-cli-usage-evals/evals.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/spec_guard.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_affinity_client_wrapper_additional_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_api_key_file_formats.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_api_key_resolution.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_api_version.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_api_version_per_operation.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_async_file_download_streaming.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_batch_get.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_api_version.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_column_limiting.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_command_context.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_company_cmds_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_company_get.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_context_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_date_utils.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_datetime_formatting.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_datetime_header_offsets.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_domain_linkification.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_dotenv_resolution.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_dropdown_field_writes.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_enriched_field_writes.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_entity_field_writes.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_entity_files_dump.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_entry_field.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_entry_field_batch_writes.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_entry_field_multi_value_limits.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_error_hints.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_error_rendering.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_field_utils.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_field_utils_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_field_utils_set_phase.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_field_value_humanization.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_file_url.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_files_ls.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_files_read.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_get_interaction_dates.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_help_json.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_interaction_date_chunking.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_interaction_utils.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_json_safety.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_list_export_entity_scope.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_list_export_field_refresh.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_list_export_filter_safety.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_list_export_truncation_meta.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_missing_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_multi_value_truncation_warnings.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_no_network_commands.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_opportunity_cmds_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_pager_logic.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_person_cmds_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_person_get.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_progress_manager.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_aggregates.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_cmd.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_cmd_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_dates.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_executor.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_expand_interactions.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_filters.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_integration.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_parser.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_planner.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_safety.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_schema.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_rate_limit_rendering.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_rate_limit_throttle.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_render_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_resolve_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_resolve_url_parsing.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_result_summary.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_safe_field_writes.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_search.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_serialization.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_session_cache.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_types.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_unreplied.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_update_check.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_v1_parsing.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_companies_create_dedup.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_companies_filter_rejection.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_compare.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_env_helpers.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_exceptions_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_field_resolver.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_field_service_caching.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_field_types_c4.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_field_value_type.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_field_values_get_value.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_file_batch_get.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_file_download_streaming.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_file_list_batch.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_file_upload_helpers_and_validation.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_files_upload_returning_files.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_filters.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_generate_mcp_command_registry.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_get_fields_filter_includes.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_get_fields_pagination.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_get_first.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_hidden_field_values.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_hooks.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_http_client_additional_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_http_client_remaining_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_inbound_webhooks.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_integration_smoke.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_interaction_date_validation.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_interactions_and_files_regressions.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_isodatetime.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_list_entry_membership_and_opportunities.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_list_term.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_bundle_env_and_completions.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_entity_dossier.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_gateway_limits.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_history_bulk_gateway.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_limits.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_read_truncation.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_resource_scripts.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_models_v2_2026_fields.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_multi_value_limits.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_new_features.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_notes_v2.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_opportunities_filter_rejection.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_org_reads.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_pagination_iterators.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_persons_create_dedup.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_persons_filter_rejection.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_public_api.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_raw_pipeline_hook_events.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_sdk_interaction_dates.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_search.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_service_get_parameter_combinations.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_companies_coverage_gaps.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_dropdown_options.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_entity_field_updates.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_field_value_changes.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_list_entries_filter_paths.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_lists_coverage_gaps.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_opportunities_additional_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_opportunities_coverage_gaps.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_opportunities_tasks_additional_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_persons_companies_additional_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_v1_only_coverage_gaps.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_small_modules_coverage.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_spec_guard.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/unit/__init__.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/unit/test_exceptions.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/__init__.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/check_cli_patterns.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/generate_mcp_command_registry.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/generate_release_notes.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/generate_requirements_mapping.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/openapi_snapshots/2024-01-01.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/openapi_snapshots/2026-07-15.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/openapi_snapshots/2026-09-17.json +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/sync_mcp_bundle_env.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/sync_mcp_registry.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/sync_mcp_version.py +0 -0
- {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/validate_mcp_registry_metadata.py +0 -0
|
@@ -224,6 +224,9 @@ jobs:
|
|
|
224
224
|
echo "Skipping traceability mapping (docs/internal not present in repo checkout)."
|
|
225
225
|
fi
|
|
226
226
|
|
|
227
|
+
- name: API coverage ledger matches the pinned specs
|
|
228
|
+
run: python tools/api_coverage.py --check
|
|
229
|
+
|
|
227
230
|
- name: MCP commands registry is valid
|
|
228
231
|
run: |
|
|
229
232
|
# Verify registry file exists and is valid JSON with expected structure
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Cowork plugin tests (replay)
|
|
2
|
+
|
|
3
|
+
# Replays the recorded cowork-harness runs of the xaffinity-cli plugin (tests/cowork). No token,
|
|
4
|
+
# Docker or model: it re-checks the recorded runs, and fails when the plugin, a scenario or a
|
|
5
|
+
# session changed since recording (re-record with tests/cowork/record.sh) or when a cassette
|
|
6
|
+
# holds data the privacy scan flags.
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
push:
|
|
10
|
+
branches: [main]
|
|
11
|
+
pull_request:
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
env:
|
|
17
|
+
HARNESS: cowork-harness@4.7.1 # the version that recorded the cassettes
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
replay:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
- uses: actions/setup-node@v4
|
|
25
|
+
with:
|
|
26
|
+
node-version: "22"
|
|
27
|
+
- name: Lint scenarios
|
|
28
|
+
run: npx --yes "$HARNESS" lint tests/cowork/scenarios/
|
|
29
|
+
- name: Replay cassettes
|
|
30
|
+
run: npx --yes "$HARNESS" replay tests/cowork/cassettes/ --output-format json | jq -e '.ok'
|
|
31
|
+
- name: Verify cassettes (staleness and privacy)
|
|
32
|
+
working-directory: tests/cowork
|
|
33
|
+
run: npx --yes "$HARNESS" verify-cassettes cassettes/ --allow-patterns-file privacy-allow.txt
|
|
@@ -40,6 +40,19 @@ jobs:
|
|
|
40
40
|
# Uses the full mcp-bash installed above; the vendored runtime has no validate.
|
|
41
41
|
run: ./mcp/xaffinity-mcp.sh validate
|
|
42
42
|
|
|
43
|
+
- uses: actions/setup-python@v6
|
|
44
|
+
with:
|
|
45
|
+
python-version: '3.12'
|
|
46
|
+
|
|
47
|
+
- name: Install the CLI from this checkout
|
|
48
|
+
run: python -m pip install -e ".[cli]"
|
|
49
|
+
|
|
50
|
+
- name: MCP tool tests (dry runs; no key, API unreachable)
|
|
51
|
+
env:
|
|
52
|
+
AFFINITY_V1_BASE_URL: http://127.0.0.1:9
|
|
53
|
+
AFFINITY_V2_BASE_URL: http://127.0.0.1:9/v2
|
|
54
|
+
run: ./mcp/test/run.sh
|
|
55
|
+
|
|
43
56
|
- name: Build MCP plugin ZIP
|
|
44
57
|
run: make -C mcp plugin
|
|
45
58
|
|
|
@@ -9,8 +9,11 @@ repos:
|
|
|
9
9
|
- id: check-toml
|
|
10
10
|
- id: check-yaml
|
|
11
11
|
- id: end-of-file-fixer
|
|
12
|
+
exclude: ^tests/cowork/cassettes/ # recorded byte-for-byte
|
|
12
13
|
- id: mixed-line-ending
|
|
14
|
+
exclude: ^tests/cowork/cassettes/ # recorded byte-for-byte
|
|
13
15
|
- id: trailing-whitespace
|
|
16
|
+
exclude: ^tests/cowork/cassettes/ # recorded byte-for-byte
|
|
14
17
|
|
|
15
18
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
16
19
|
rev: v1.15.0
|
|
@@ -7,12 +7,186 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.0.0] - 2026-10-12
|
|
11
|
+
|
|
12
|
+
### Highlights
|
|
13
|
+
|
|
14
|
+
**SDK 2.0 moves to Affinity's V2 API wherever V2 can do the job.** Webhooks, reminders, note
|
|
15
|
+
writes, list get/create, file reads (new `files.get_v2`/`list_v2`) and the rate-limit endpoint
|
|
16
|
+
now use V2; the CLI gains `xaffinity webhook ls|get|create|update|delete`. V1 stays only where
|
|
17
|
+
V2 can't do it, and for person create/delete, opportunity rename/delete and adding to a list,
|
|
18
|
+
which the V2 spec documents but the API didn't serve when tested. **Breaking:** webhook and
|
|
19
|
+
reminder models change shape, note writes return `NoteV2`, `add_opportunity()` is removed, and
|
|
20
|
+
operations added in newer Affinity API versions refuse a client pinned to an older one
|
|
21
|
+
(`ApiVersionTooOldError`). See the [Migrating to 2.0](https://yaniv-golan.github.io/affinity-sdk/latest/guides/migrating-to-2/)
|
|
22
|
+
guide.
|
|
23
|
+
|
|
24
|
+
### Changed (breaking)
|
|
25
|
+
|
|
26
|
+
- **Webhooks use the V2 API** (`/v2/webhooks`, Affinity API 2026-07-15 or later, beta).
|
|
27
|
+
`WebhookSubscription` is now `Webhook`: `webhook_url` → `url`, `disabled` →
|
|
28
|
+
`status` (`WebhookStatus.ACTIVE`/`DISABLED`), `created_by` → `creator` (`PersonRef`), plus
|
|
29
|
+
`created_at`/`updated_at`. `WebhookCreate(url=…, subscriptions=[…])` requires `subscriptions`
|
|
30
|
+
(`[]` = every event type). `WebhookUpdate` takes `url`, `subscriptions`, `status` and sends
|
|
31
|
+
only what is set. `list()` returns one page (`ids`, created/updated ranges, `limit`,
|
|
32
|
+
`cursor`); `iter()` returns every webhook. `update()` returns the webhook as read back (two
|
|
33
|
+
requests); `delete()` returns `None`. 1.x field names raise `ValidationError` instead of being
|
|
34
|
+
ignored. Without permission to manage all webhooks, the API lists, reads and changes only the
|
|
35
|
+
caller's own webhooks. A client pinned to API version 2024-01-01 gets
|
|
36
|
+
`ApiVersionTooOldError`.
|
|
37
|
+
- **Reminders use the V2 API** (`/v2/reminders`; `get`/`delete` need API 2026-07-15, `update`
|
|
38
|
+
2026-09-17). `Reminder` has the V2 shape: `creator`, `owner`, `completer`, `person` are
|
|
39
|
+
`PersonRef` (id only; look names up separately), `company`/`opportunity` are
|
|
40
|
+
`CompanyRef`/`OpportunityRef`, recurrence is `recurrence` (`period_days`, `reset_type`; the
|
|
41
|
+
read-only `reset_type`/`reminder_days` properties still work), plus `updated_at`.
|
|
42
|
+
`ReminderType`, `ReminderResetType` and `ReminderStatus` are string enums with the V2 values
|
|
43
|
+
(member names unchanged; the 1.x integers are still accepted); `ReminderResetType.MEETING` is
|
|
44
|
+
now an alias of `EVENT`. `list()` takes `limit` (1-100), `cursor`, `ids` and created/updated
|
|
45
|
+
ranges instead of `page_size`/`page_token`, and returns reminders soonest-due first.
|
|
46
|
+
`update()` sends only the fields that are set (`clear_content=True` removes the content) and
|
|
47
|
+
returns the reminder as read back. `list_batch()` is on the sync client too, and fetches up to
|
|
48
|
+
50 entities per request. Kept on V1 where V2 can't do it: changing a reminder's type, and updating or deleting a
|
|
49
|
+
reminder you didn't create and don't own (V2 refuses; the SDK retries through V1). A reminder
|
|
50
|
+
must be attached to one person, company or opportunity (both APIs require it; the SDK now
|
|
51
|
+
says so before sending).
|
|
52
|
+
- **Note writes use the V2 API** (`notes.create`, `update`, `delete`; reads are unchanged).
|
|
53
|
+
`create()` and `update()` return `NoteV2` (`content.html`, `creator`; `update()` reads the note
|
|
54
|
+
back with its attachments, two requests). V2 stores notes as HTML: plain text (the default
|
|
55
|
+
`type`) is escaped and wrapped in paragraphs, and `NoteUpdate` takes `type` too (plain text
|
|
56
|
+
unless set to `HTML`, whatever the note was before). With `type=NoteType.HTML`, `<b>`/`<i>`
|
|
57
|
+
become `<strong>`/`<em>`, and what the API rejects (style/class attributes, img, pre, code,
|
|
58
|
+
blockquote, mention spans, non-http(s)/mailto links) raises `ValueError` naming the allowed
|
|
59
|
+
tags. A reply (`parent_id`) with persons/companies/opportunities raises instead of ignoring
|
|
60
|
+
them; `AI_NOTETAKER`/`EMAIL_DERIVED` can't be created. `NoteUpdate` can replace a note's
|
|
61
|
+
persons, companies and opportunities (`[]` clears). Changing the text of a note that
|
|
62
|
+
@mentions people is refused by the API; the error now says so. `NoteV2` and `NoteContent`
|
|
63
|
+
are exported from `affinity.models`.
|
|
64
|
+
- **`rate_limits.refresh()` reads `GET /v2/rate-limit`** (API 2026-07-15+), falling back to
|
|
65
|
+
response headers as before (now also when the client is pinned to an older API version).
|
|
66
|
+
`RateLimitSnapshot` is unchanged; `RateLimits` also reads the V2 names (`callerPerMinute`,
|
|
67
|
+
`orgPerMonth`).
|
|
68
|
+
- **Lists: `get()` and `create()` use the V2 API.** `get()` no longer fills `fields` (use
|
|
69
|
+
`get_fields()`) or `additional_permissions`; it sets `created_at`. `get_size()` still reads
|
|
70
|
+
the size from V1 (V2 has none). `create()` makes the caller the owner; a public list needs the
|
|
71
|
+
"Share accessible Lists globally" permission. A list created with `owner_id` or
|
|
72
|
+
`additional_permissions` still goes through V1.
|
|
73
|
+
- **`entries(list_id).add_opportunity()` is removed.** Opportunities can't be added to a list
|
|
74
|
+
as entries: create them on their list with `opportunities.create(OpportunityCreate(list_id=...))`.
|
|
75
|
+
- Person create/delete, opportunity rename/delete and adding to a list stay on V1: the V2 spec
|
|
76
|
+
documents them, but Affinity didn't serve them when tested (2026-10-12).
|
|
77
|
+
|
|
78
|
+
### Added
|
|
79
|
+
|
|
80
|
+
- **`files.get_v2()`, `files.list_v2()`, `files.iter_v2()`** (V2, Affinity API 2026-09-17+):
|
|
81
|
+
a file's metadata with a download URL that expires after 60 seconds, and every file visible to
|
|
82
|
+
you across the organization, newest first (filter by created date and uploader). `FileV2`
|
|
83
|
+
model. `files.get/list/iter` stay on V1: only V1 lists one entity's files.
|
|
84
|
+
- **CLI `webhook ls|get|create|update|delete`.** `create` takes `--url` and `--event`
|
|
85
|
+
(repeatable) or `--all-events`; `update` takes `--url`, `--event`/`--all-events`, `--status
|
|
86
|
+
active|disabled`. `create`, `update` and `delete` ask for confirmation (`--yes` in scripts),
|
|
87
|
+
since a webhook sends CRM events to an outside URL. Rows include `allEvents`.
|
|
88
|
+
- **CLI `list get <id>`** no longer prints `.data.list.fields` (the fields are in `.data.fields`
|
|
89
|
+
as before), `additionalPermissions` is always `[]`, and `createdAt` is added; `list create
|
|
90
|
+
--owner-id` creates the list through V1.
|
|
91
|
+
- **CLI `reminder create/update --reminder-days`** help now says what it is: the days between a
|
|
92
|
+
recurring reminder's due dates.
|
|
93
|
+
- **CLI `note update --type plain-text|html`**; `note create --type` is now plain-text or html
|
|
94
|
+
(Affinity creates the other kinds itself). `note create`/`update` output keeps the `note get`
|
|
95
|
+
keys (`type` is `html`; content is the stored HTML). The duplicate-note warning still finds
|
|
96
|
+
an earlier copy: V1 shows notes stored as HTML in a markdown form, which the check allows for.
|
|
97
|
+
- **CLI `reminder update --clear-content`**; `reminder ls --page-size` is now at most 100, and
|
|
98
|
+
rows include `updatedAt`; `--reset-type event` (`meeting` still accepted, printed as `event`).
|
|
99
|
+
- **MCP:** the webhook commands are in the command registry; `webhook create`/`update`/`delete`
|
|
100
|
+
go through the same user confirmation as deletes, and the confirmation says why (events sent
|
|
101
|
+
to an outside URL).
|
|
102
|
+
|
|
103
|
+
### Fixed
|
|
104
|
+
|
|
105
|
+
- `Person.company_ids` and `Opportunity.company_ids` are now read from V1 responses
|
|
106
|
+
(`organization_ids`), e.g. from `persons.create()` with companies, `persons.update()`,
|
|
107
|
+
`opportunities.update()` and `get_details()`; they were always empty.
|
|
108
|
+
|
|
109
|
+
### Docs
|
|
110
|
+
|
|
111
|
+
- New **API coverage** reference page: every Affinity API operation (V2 and V1) and how the SDK
|
|
112
|
+
supports it — the SDK call, an equivalent operation, or the planned release — with beta
|
|
113
|
+
operations and the minimum API version marked.
|
|
114
|
+
|
|
115
|
+
### Internal
|
|
116
|
+
|
|
117
|
+
- `tools/api_coverage.py` and the ledger `tools/api_coverage.json` (CI: `--check`): every
|
|
118
|
+
operation in the pinned V2 snapshots and the new V1 snapshot (`tools/api_coverage_v1_snapshot.json`,
|
|
119
|
+
59 operations) has exactly one row. `tests/test_api_coverage.py` runs each supported row's call,
|
|
120
|
+
sync and async, against a recording HTTP layer and checks the method, path and API version it
|
|
121
|
+
requests.
|
|
122
|
+
|
|
123
|
+
### Plugins
|
|
124
|
+
|
|
125
|
+
- **SDK plugin**: 1.7.1 → 2.0.0 (matches SDK 2.0) — skill: note writes go through V2 (HTML, the
|
|
126
|
+
allowed tags), and `add_opportunity()` is gone (create the opportunity on its list).
|
|
127
|
+
- **CLI plugin**: 1.13.6 → 2.0.0 (matches CLI 2.0; no content change).
|
|
128
|
+
- **MCP**: 1.32.2 → 2.0.0 (requires CLI 2.0.0; see `mcp/CHANGELOG.md`).
|
|
129
|
+
- **CLI plugin**: 1.13.5 → 1.13.6 — skill: the Cowork install line adds
|
|
130
|
+
`--no-warn-script-location` (pip's "not on PATH" warning was noise; the skill adds the folder to
|
|
131
|
+
PATH in each call), and the Cowork key paths (`--env-file`, `AFFINITY_API_KEY_FILE`) are quoted,
|
|
132
|
+
so connected folders with spaces in their names work.
|
|
133
|
+
- **CLI plugin**: 1.13.4 → 1.13.5 — no `clis` credential declaration. In local Cowork it routed
|
|
134
|
+
every `xaffinity` call through Desktop's CLI credential broker, which isn't enabled yet and
|
|
135
|
+
refuses the call ("cli-wrapper: plugin oauth disabled"), so the CLI never ran whatever key the
|
|
136
|
+
VM had. Cowork's plugin settings no longer show an Affinity API Key field. The VM has no
|
|
137
|
+
`xaffinity` of its own, so the skill now installs it when it's missing (`pip install --user`,
|
|
138
|
+
about 10s, once per task) and puts `~/.local/bin` on PATH in each call; the CLI then reads the
|
|
139
|
+
key as the skill describes (a connected folder's `.env` with `--env-file`, or a key file).
|
|
140
|
+
- **CLI plugin**: 1.13.3 → 1.13.4 — in local Cowork the plugin's hooks run on the host Mac, not
|
|
141
|
+
in the VM where the CLI runs, so the key check saw the Mac's key (or none) and could deny every
|
|
142
|
+
data command even with a key set in Cowork. There the hooks now do nothing; a missing key
|
|
143
|
+
shows up as the CLI's own error. Cloud Cowork and Claude Code keep the check. The `.env` read
|
|
144
|
+
guard's message no longer claims the key is in the environment.
|
|
145
|
+
|
|
146
|
+
## [1.29.0] - 2026-10-11
|
|
147
|
+
|
|
148
|
+
### Highlights
|
|
149
|
+
|
|
150
|
+
**`field history-bulk` works on global fields.** A global field's changes (a company or person
|
|
151
|
+
field shown on a list) belong to the company or person, not to the list entry, so reading them
|
|
152
|
+
per entry returned nothing, with no warning. They are now read per company/person, or
|
|
153
|
+
field-wide when the field's history is small, and each row carries the company's entry on the
|
|
154
|
+
list.
|
|
155
|
+
|
|
156
|
+
### Fixed
|
|
157
|
+
|
|
158
|
+
- `field history-bulk` on a global field returned no rows. It now reads per company or person
|
|
159
|
+
(one call each; entries sharing one are read once, with a warning) and fills `listEntryId`
|
|
160
|
+
with the entry on the list. With `--all` on 100+ of them it reads the field's org-wide history
|
|
161
|
+
instead when that fits in one call; a forced `--strategy field` reads up to 200,000 changes and
|
|
162
|
+
otherwise stops with an error. Rows include changes from before the company joined the list.
|
|
163
|
+
- `field history-bulk` with a field that isn't on the list, or an enriched field, gave empty
|
|
164
|
+
results; both are usage errors now. So is a global field with `--list-entry-ids`, which can't
|
|
165
|
+
map entries to companies.
|
|
166
|
+
- `field history --list-entry-id` on a global field returned nothing; it now says the field is
|
|
167
|
+
global and to use `--company-id` / `--person-id`.
|
|
168
|
+
- `config check-key`: when the key comes from a `.env` outside the current directory (e.g.
|
|
169
|
+
`--env-file` with a Cowork connected folder, where each shell call starts above it), the
|
|
170
|
+
suggested `pattern` names it with `--env-file <path>`, so later commands find it too.
|
|
171
|
+
|
|
172
|
+
### Changed
|
|
173
|
+
|
|
174
|
+
- `field history-bulk` reads field-wide 10,000 changes per call (was 500): fewer calls for list
|
|
175
|
+
fields too. The dry run reports `fieldKind` (`list` / `global`) and, for a global field,
|
|
176
|
+
`entities`.
|
|
177
|
+
|
|
178
|
+
### Plugins
|
|
179
|
+
|
|
180
|
+
- **CLI plugin**: 1.13.2 → 1.13.3 — skill: `history-bulk` on global fields; Cowork keys in a
|
|
181
|
+
connected folder need `--env-file /sessions/<id>/mnt/<folder>/.env` (each shell call starts
|
|
182
|
+
in the session root), and the check-key `pattern` carries it.
|
|
183
|
+
|
|
10
184
|
## [1.28.0] - 2026-10-11
|
|
11
185
|
|
|
12
186
|
### Highlights
|
|
13
187
|
|
|
14
|
-
**Read the API key from 1Password.** `AFFINITY_API_KEY_FILE` (and `--api-key-file`)
|
|
15
|
-
`.env` file and a named pipe, so
|
|
188
|
+
**Read the API key from 1Password Environments.** `AFFINITY_API_KEY_FILE` (and `--api-key-file`)
|
|
189
|
+
accept a `.env` file and a named pipe, so an Environment's locally mounted `.env` file works directly:
|
|
16
190
|
the CLI waits for 1Password to supply the key after you approve the read, and the key never
|
|
17
191
|
touches the disk.
|
|
18
192
|
|
|
@@ -23,7 +197,7 @@ touches the disk.
|
|
|
23
197
|
error. A named pipe is read when its writer supplies the content, waiting up to 30 seconds,
|
|
24
198
|
with a message naming 1Password if nothing arrives. `config check-key` reports a named pipe as
|
|
25
199
|
configured without reading it, and skips its API-version probe for it (reading would prompt).
|
|
26
|
-
Tested with a 1Password Environments
|
|
200
|
+
Tested with a real 1Password Environments locally mounted `.env` file: approval and unlock prompts, repeated and
|
|
27
201
|
concurrent reads.
|
|
28
202
|
|
|
29
203
|
### Changed
|
|
@@ -40,7 +214,7 @@ touches the disk.
|
|
|
40
214
|
- **CLI plugin**: 1.13.0 → 1.13.1 — skill describes the current CLI only (no per-version notes);
|
|
41
215
|
one upgrade hint at install.
|
|
42
216
|
- **CLI plugin**: 1.13.1 → 1.13.2 — skill: `AFFINITY_API_KEY_FILE` reads `.env` files and
|
|
43
|
-
1Password mounted `.env`
|
|
217
|
+
1Password Environments locally mounted `.env` files; forced `--strategy field` never falls back.
|
|
44
218
|
- **SDK plugin**: 1.7.0 → 1.7.1 — skill: API version pinning, note/file/semantic company search,
|
|
45
219
|
hidden values; new `references/services.md` organised by question (field history, org-wide
|
|
46
220
|
activity, notes V2 and replies, transcripts, relationships, merges, dropdown options, uploads).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: affinity-sdk
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
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/
|
|
@@ -373,8 +373,8 @@ with Affinity(api_key="your-key") as client:
|
|
|
373
373
|
```python
|
|
374
374
|
from datetime import datetime, timedelta
|
|
375
375
|
from affinity import Affinity
|
|
376
|
-
from affinity.models import ReminderCreate
|
|
377
|
-
from affinity.types import PersonId, ReminderResetType, ReminderType, UserId
|
|
376
|
+
from affinity.models import ReminderCreate, ReminderUpdate
|
|
377
|
+
from affinity.types import PersonId, ReminderResetType, ReminderStatus, ReminderType, UserId
|
|
378
378
|
|
|
379
379
|
with Affinity(api_key="your-key") as client:
|
|
380
380
|
# Get current user
|
|
@@ -402,6 +402,14 @@ with Affinity(api_key="your-key") as client:
|
|
|
402
402
|
person_id=PersonId(123),
|
|
403
403
|
)
|
|
404
404
|
)
|
|
405
|
+
|
|
406
|
+
# Complete it (a recurring reminder moves to its next due date)
|
|
407
|
+
client.reminders.update(recurring.id, ReminderUpdate(is_completed=True))
|
|
408
|
+
|
|
409
|
+
# Overdue reminders for many people, one request per 50 people
|
|
410
|
+
overdue = client.reminders.list_batch(
|
|
411
|
+
person_ids=[PersonId(123), PersonId(456)], status=ReminderStatus.OVERDUE
|
|
412
|
+
)
|
|
405
413
|
```
|
|
406
414
|
|
|
407
415
|
### Files
|
|
@@ -456,13 +464,13 @@ with Affinity(api_key="your-key") as client:
|
|
|
456
464
|
```python
|
|
457
465
|
from affinity import Affinity
|
|
458
466
|
from affinity.models import WebhookCreate, WebhookUpdate
|
|
459
|
-
from affinity.types import WebhookEvent
|
|
467
|
+
from affinity.types import WebhookEvent, WebhookStatus
|
|
460
468
|
|
|
461
469
|
with Affinity(api_key="your-key") as client:
|
|
462
|
-
# Create a webhook
|
|
470
|
+
# Create a webhook (subscriptions is required; [] means every event type)
|
|
463
471
|
webhook = client.webhooks.create(
|
|
464
472
|
WebhookCreate(
|
|
465
|
-
|
|
473
|
+
url="https://your-server.com/webhook",
|
|
466
474
|
subscriptions=[
|
|
467
475
|
WebhookEvent.LIST_ENTRY_CREATED,
|
|
468
476
|
WebhookEvent.LIST_ENTRY_DELETED,
|
|
@@ -471,14 +479,12 @@ with Affinity(api_key="your-key") as client:
|
|
|
471
479
|
)
|
|
472
480
|
)
|
|
473
481
|
|
|
474
|
-
#
|
|
475
|
-
|
|
482
|
+
# All webhooks you can see (all of them if you may manage all webhooks)
|
|
483
|
+
for hook in client.webhooks.iter():
|
|
484
|
+
print(hook.id, hook.url, hook.status)
|
|
476
485
|
|
|
477
|
-
#
|
|
478
|
-
client.webhooks.update(
|
|
479
|
-
webhook.id,
|
|
480
|
-
WebhookUpdate(disabled=True)
|
|
481
|
-
)
|
|
486
|
+
# Pause a webhook (returns it as read back)
|
|
487
|
+
client.webhooks.update(webhook.id, WebhookUpdate(status=WebhookStatus.DISABLED))
|
|
482
488
|
```
|
|
483
489
|
|
|
484
490
|
### Rate Limits
|
|
@@ -545,9 +551,9 @@ those to V2 is planned.
|
|
|
545
551
|
| List Entries (write) | Create | ✅ | V1 |
|
|
546
552
|
| Field Values (read) | ✅ | ✅ | V2 |
|
|
547
553
|
| Field Values (write) | ✅ | ✅ | V2 (list entries), V1 (companies/persons) |
|
|
548
|
-
| Notes | ✅ | ✅ | V1 |
|
|
549
|
-
| Reminders | ✅ | ✅ | V1 |
|
|
550
|
-
| Webhooks | ✅ | ✅ |
|
|
554
|
+
| Notes | ✅ | ✅ | V1 reads; V2 writes |
|
|
555
|
+
| Reminders | ✅ | ✅ | V2 (V1 for type changes, and when V2 refuses a non-owner) |
|
|
556
|
+
| Webhooks | ✅ | ✅ | V2 |
|
|
551
557
|
| Interactions | Read-only | ✅ | V1 |
|
|
552
558
|
| Entity Files | Read-only | ✅ | V1 |
|
|
553
559
|
| Relationship Strengths | ✅ | ✅ | V1 |
|
|
@@ -697,7 +703,7 @@ async def main():
|
|
|
697
703
|
asyncio.run(main())
|
|
698
704
|
```
|
|
699
705
|
|
|
700
|
-
Async support mirrors the sync client surface area (including V1
|
|
706
|
+
Async support mirrors the sync client surface area (including the V1 services like notes and files).
|
|
701
707
|
|
|
702
708
|
See `docs/public/guides/sync-vs-async.md` for more details.
|
|
703
709
|
|
|
@@ -312,8 +312,8 @@ with Affinity(api_key="your-key") as client:
|
|
|
312
312
|
```python
|
|
313
313
|
from datetime import datetime, timedelta
|
|
314
314
|
from affinity import Affinity
|
|
315
|
-
from affinity.models import ReminderCreate
|
|
316
|
-
from affinity.types import PersonId, ReminderResetType, ReminderType, UserId
|
|
315
|
+
from affinity.models import ReminderCreate, ReminderUpdate
|
|
316
|
+
from affinity.types import PersonId, ReminderResetType, ReminderStatus, ReminderType, UserId
|
|
317
317
|
|
|
318
318
|
with Affinity(api_key="your-key") as client:
|
|
319
319
|
# Get current user
|
|
@@ -341,6 +341,14 @@ with Affinity(api_key="your-key") as client:
|
|
|
341
341
|
person_id=PersonId(123),
|
|
342
342
|
)
|
|
343
343
|
)
|
|
344
|
+
|
|
345
|
+
# Complete it (a recurring reminder moves to its next due date)
|
|
346
|
+
client.reminders.update(recurring.id, ReminderUpdate(is_completed=True))
|
|
347
|
+
|
|
348
|
+
# Overdue reminders for many people, one request per 50 people
|
|
349
|
+
overdue = client.reminders.list_batch(
|
|
350
|
+
person_ids=[PersonId(123), PersonId(456)], status=ReminderStatus.OVERDUE
|
|
351
|
+
)
|
|
344
352
|
```
|
|
345
353
|
|
|
346
354
|
### Files
|
|
@@ -395,13 +403,13 @@ with Affinity(api_key="your-key") as client:
|
|
|
395
403
|
```python
|
|
396
404
|
from affinity import Affinity
|
|
397
405
|
from affinity.models import WebhookCreate, WebhookUpdate
|
|
398
|
-
from affinity.types import WebhookEvent
|
|
406
|
+
from affinity.types import WebhookEvent, WebhookStatus
|
|
399
407
|
|
|
400
408
|
with Affinity(api_key="your-key") as client:
|
|
401
|
-
# Create a webhook
|
|
409
|
+
# Create a webhook (subscriptions is required; [] means every event type)
|
|
402
410
|
webhook = client.webhooks.create(
|
|
403
411
|
WebhookCreate(
|
|
404
|
-
|
|
412
|
+
url="https://your-server.com/webhook",
|
|
405
413
|
subscriptions=[
|
|
406
414
|
WebhookEvent.LIST_ENTRY_CREATED,
|
|
407
415
|
WebhookEvent.LIST_ENTRY_DELETED,
|
|
@@ -410,14 +418,12 @@ with Affinity(api_key="your-key") as client:
|
|
|
410
418
|
)
|
|
411
419
|
)
|
|
412
420
|
|
|
413
|
-
#
|
|
414
|
-
|
|
421
|
+
# All webhooks you can see (all of them if you may manage all webhooks)
|
|
422
|
+
for hook in client.webhooks.iter():
|
|
423
|
+
print(hook.id, hook.url, hook.status)
|
|
415
424
|
|
|
416
|
-
#
|
|
417
|
-
client.webhooks.update(
|
|
418
|
-
webhook.id,
|
|
419
|
-
WebhookUpdate(disabled=True)
|
|
420
|
-
)
|
|
425
|
+
# Pause a webhook (returns it as read back)
|
|
426
|
+
client.webhooks.update(webhook.id, WebhookUpdate(status=WebhookStatus.DISABLED))
|
|
421
427
|
```
|
|
422
428
|
|
|
423
429
|
### Rate Limits
|
|
@@ -484,9 +490,9 @@ those to V2 is planned.
|
|
|
484
490
|
| List Entries (write) | Create | ✅ | V1 |
|
|
485
491
|
| Field Values (read) | ✅ | ✅ | V2 |
|
|
486
492
|
| Field Values (write) | ✅ | ✅ | V2 (list entries), V1 (companies/persons) |
|
|
487
|
-
| Notes | ✅ | ✅ | V1 |
|
|
488
|
-
| Reminders | ✅ | ✅ | V1 |
|
|
489
|
-
| Webhooks | ✅ | ✅ |
|
|
493
|
+
| Notes | ✅ | ✅ | V1 reads; V2 writes |
|
|
494
|
+
| Reminders | ✅ | ✅ | V2 (V1 for type changes, and when V2 refuses a non-owner) |
|
|
495
|
+
| Webhooks | ✅ | ✅ | V2 |
|
|
490
496
|
| Interactions | Read-only | ✅ | V1 |
|
|
491
497
|
| Entity Files | Read-only | ✅ | V1 |
|
|
492
498
|
| Relationship Strengths | ✅ | ✅ | V1 |
|
|
@@ -636,7 +642,7 @@ async def main():
|
|
|
636
642
|
asyncio.run(main())
|
|
637
643
|
```
|
|
638
644
|
|
|
639
|
-
Async support mirrors the sync client surface area (including V1
|
|
645
|
+
Async support mirrors the sync client surface area (including the V1 services like notes and files).
|
|
640
646
|
|
|
641
647
|
See `docs/public/guides/sync-vs-async.md` for more details.
|
|
642
648
|
|
|
@@ -59,7 +59,8 @@ _ENV_LINE = re.compile(r"^\s*(?:export\s+)?([A-Z][A-Z0-9_]*)\s*=\s*(.*)$")
|
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
def _read_fifo(path: Path, timeout: float) -> str:
|
|
62
|
-
"""Read a named pipe whose writer may appear later (e.g. a 1Password
|
|
62
|
+
"""Read a named pipe whose writer may appear later (e.g. a 1Password Environments locally
|
|
63
|
+
mounted .env file).
|
|
63
64
|
|
|
64
65
|
Opened non-blocking so a missing writer can't hang the process: reads return nothing until
|
|
65
66
|
a writer has written, and end once it closes.
|
|
@@ -80,7 +81,8 @@ def _read_fifo(path: Path, timeout: float) -> str:
|
|
|
80
81
|
if time.monotonic() > deadline:
|
|
81
82
|
raise ValueError(
|
|
82
83
|
f"Timed out after {timeout:g}s waiting for {path} (a named pipe). If it is "
|
|
83
|
-
"a 1Password mounted .env: is 1Password running, and
|
|
84
|
+
"a 1Password Environments locally mounted .env file: is 1Password running, and "
|
|
85
|
+
"was the read approved?"
|
|
84
86
|
)
|
|
85
87
|
if not chunk:
|
|
86
88
|
time.sleep(0.05)
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import getpass
|
|
4
4
|
import os
|
|
5
5
|
import re
|
|
6
|
+
import shlex
|
|
6
7
|
import stat
|
|
7
8
|
import sys
|
|
8
9
|
from contextlib import suppress
|
|
@@ -126,8 +127,8 @@ def _find_existing_key(ctx: CLIContext) -> tuple[bool, str | None]:
|
|
|
126
127
|
if file_path_env:
|
|
127
128
|
try:
|
|
128
129
|
file_path = Path(file_path_env).expanduser()
|
|
129
|
-
# A named pipe (e.g. a 1Password mounted .env) is not read
|
|
130
|
-
# 1Password for approval. Its existence is the evidence.
|
|
130
|
+
# A named pipe (e.g. a 1Password Environments locally mounted .env file) is not read
|
|
131
|
+
# here: reading it asks 1Password for approval. Its existence is the evidence.
|
|
131
132
|
if file_path.exists() and stat.S_ISFIFO(file_path.stat().st_mode):
|
|
132
133
|
return True, "file"
|
|
133
134
|
if file_path.is_file() and file_path.read_text(encoding="utf-8").strip():
|
|
@@ -212,7 +213,16 @@ def check_key(ctx: CLIContext) -> None:
|
|
|
212
213
|
pattern: str | None = None
|
|
213
214
|
if key_found:
|
|
214
215
|
if source == "dotenv":
|
|
215
|
-
|
|
216
|
+
env_file = Path(ctx.env_file).resolve()
|
|
217
|
+
if env_file == (Path.cwd() / ".env").resolve():
|
|
218
|
+
pattern = "xaffinity --dotenv --readonly <command> --json"
|
|
219
|
+
else:
|
|
220
|
+
# Not in the current directory (e.g. Cowork, where each shell call starts
|
|
221
|
+
# above the connected folder): name it, or later commands won't find it
|
|
222
|
+
pattern = (
|
|
223
|
+
f"xaffinity --dotenv --env-file {shlex.quote(str(env_file))} "
|
|
224
|
+
"--readonly <command> --json"
|
|
225
|
+
)
|
|
216
226
|
else:
|
|
217
227
|
pattern = "xaffinity --readonly <command> --json"
|
|
218
228
|
|
|
@@ -248,7 +258,8 @@ def _probe_key_default_api_version(ctx: CLIContext, source: str | None) -> str |
|
|
|
248
258
|
|
|
249
259
|
One unversioned V2 request with a short timeout and no retries. Never raises, never
|
|
250
260
|
runs AFFINITY_API_KEY_COMMAND (check-key deliberately doesn't), never reads stdin and
|
|
251
|
-
never reads a named pipe (a 1Password mounted .env would
|
|
261
|
+
never reads a named pipe (a 1Password Environments locally mounted .env file would
|
|
262
|
+
prompt the user).
|
|
252
263
|
"""
|
|
253
264
|
if (
|
|
254
265
|
source == "command"
|