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.
Files changed (672) hide show
  1. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/ci.yml +3 -0
  2. affinity_sdk-2.0.0/.github/workflows/cowork-replay.yml +33 -0
  3. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/plugin-build.yml +13 -0
  4. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.gitignore +3 -0
  5. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.pre-commit-config.yaml +3 -0
  6. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/CHANGELOG.md +178 -4
  7. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/PKG-INFO +23 -17
  8. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/README.md +22 -16
  9. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/_internal/keyfile.py +4 -2
  10. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/config_cmds.py +15 -4
  11. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/field_cmds.py +208 -33
  12. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/list_cmds.py +6 -1
  13. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/note_cmds.py +148 -29
  14. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/reminder_cmds.py +157 -191
  15. affinity_sdk-2.0.0/affinity/cli/commands/webhook_cmds.py +365 -0
  16. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/confirm.py +12 -4
  17. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/main.py +2 -0
  18. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/client.py +2 -4
  19. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/inbound_webhooks.py +1 -1
  20. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/__init__.py +17 -3
  21. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/entities.py +20 -7
  22. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/secondary.py +196 -40
  23. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/types.py +57 -14
  24. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/__init__.py +4 -4
  25. affinity_sdk-2.0.0/affinity/services/_note_html.py +165 -0
  26. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/_v2_filters.py +8 -1
  27. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/lists.py +67 -63
  28. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/rate_limits.py +12 -9
  29. affinity_sdk-2.0.0/affinity/services/reminders.py +715 -0
  30. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/v1_only.py +208 -604
  31. affinity_sdk-2.0.0/affinity/services/webhooks.py +304 -0
  32. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/types.py +2 -0
  33. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/cli/commands.md +93 -7
  34. affinity_sdk-2.0.0/docs/public/guides/api-versions-and-routing.md +80 -0
  35. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/authentication.md +2 -2
  36. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/errors-and-retries.md +6 -9
  37. affinity_sdk-2.0.0/docs/public/guides/migrating-to-2.md +90 -0
  38. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/pagination.md +3 -3
  39. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/webhooks.md +45 -8
  40. affinity_sdk-2.0.0/docs/public/reference/api-coverage.md +190 -0
  41. affinity_sdk-2.0.0/docs/public/reference/services/reminders.md +5 -0
  42. affinity_sdk-2.0.0/docs/public/reference/services/v1/files.md +8 -0
  43. affinity_sdk-2.0.0/docs/public/reference/services/v1/notes.md +6 -0
  44. affinity_sdk-2.0.0/docs/public/reference/services/webhooks.md +5 -0
  45. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/plugin.json +1 -1
  46. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/skills/pipeline-history/SKILL.md +8 -6
  47. affinity_sdk-2.0.0/mcp/.mcp-bash/VERSION +1 -0
  48. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/bin/mcp-bash +11 -1
  49. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/cli/common.sh +4 -10
  50. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/core.sh +118 -8
  51. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/elicitation.sh +3 -0
  52. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/runtime.sh +25 -0
  53. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/timeout.sh +19 -6
  54. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/tools.sh +52 -6
  55. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/tools_policy.sh +48 -2
  56. affinity_sdk-2.0.0/mcp/.mcp-bash/sdk/tool-error.sh +113 -0
  57. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/sdk/tool-sdk.sh +172 -15
  58. affinity_sdk-2.0.0/mcp/.mcp-bash/vendor.json +1 -0
  59. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.registry/commands.generated.json +332 -20
  60. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.registry/mcp-commands.json +29 -1
  61. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/CHANGELOG.md +52 -0
  62. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/COMPATIBILITY +13 -2
  63. affinity_sdk-2.0.0/mcp/VERSION +1 -0
  64. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/mcp-bash.lock +2 -2
  65. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/data-model/data-model.md +2 -1
  66. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/server.d/policy.sh +4 -5
  67. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/server.d/requirements.json +1 -1
  68. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/server.d/server.meta.json +1 -1
  69. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/test/run.sh +8 -5
  70. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/execute-write-command/tool.meta.json +2 -2
  71. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/execute-write-command/tool.sh +18 -2
  72. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/query/tool.sh +1 -1
  73. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mkdocs.yml +4 -2
  74. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/affinity-sdk/.claude-plugin/plugin.json +1 -1
  75. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/affinity-sdk/.claude-plugin/skills/affinity-python-sdk/SKILL.md +1 -1
  76. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/affinity-sdk/.claude-plugin/skills/affinity-python-sdk/references/services.md +4 -1
  77. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/.claude-plugin/plugin.json +2 -16
  78. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/hooks/guard-env-read.sh +2 -2
  79. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/hooks/pre-xaffinity.sh +9 -0
  80. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/hooks/session-setup.sh +8 -0
  81. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/SKILL.md +8 -3
  82. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/history-and-activity.md +7 -2
  83. affinity_sdk-2.0.0/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/setup.md +76 -0
  84. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/pyproject.toml +1 -1
  85. affinity_sdk-2.0.0/tests/cowork/.cowork-redact.json +22 -0
  86. affinity_sdk-2.0.0/tests/cowork/README.md +54 -0
  87. affinity_sdk-2.0.0/tests/cowork/cassettes/company-lists-status.cassette.json +410 -0
  88. affinity_sdk-2.0.0/tests/cowork/cassettes/hook-blocks-without-key.cassette.json +306 -0
  89. affinity_sdk-2.0.0/tests/cowork/cassettes/no-key-skill-path.cassette.json +395 -0
  90. affinity_sdk-2.0.0/tests/cowork/cassettes/status-history.cassette.json +469 -0
  91. affinity_sdk-2.0.0/tests/cowork/fixtures/workdir-key/README.txt +2 -0
  92. affinity_sdk-2.0.0/tests/cowork/fixtures/workdir-key/xaffinity-test-key +1 -0
  93. affinity_sdk-2.0.0/tests/cowork/fixtures/workdir-nokey/README.txt +1 -0
  94. affinity_sdk-2.0.0/tests/cowork/image/Dockerfile +13 -0
  95. affinity_sdk-2.0.0/tests/cowork/image/fakeaff/build_fixtures.py +268 -0
  96. affinity_sdk-2.0.0/tests/cowork/image/fakeaff/fixtures.json +790 -0
  97. affinity_sdk-2.0.0/tests/cowork/image/fakeaff/server.py +72 -0
  98. affinity_sdk-2.0.0/tests/cowork/image/xaffinity-wrapper.sh +23 -0
  99. affinity_sdk-2.0.0/tests/cowork/privacy-allow.txt +7 -0
  100. affinity_sdk-2.0.0/tests/cowork/record.sh +50 -0
  101. affinity_sdk-2.0.0/tests/cowork/scenarios/company-lists-status.yaml +17 -0
  102. affinity_sdk-2.0.0/tests/cowork/scenarios/hook-blocks-without-key.yaml +9 -0
  103. affinity_sdk-2.0.0/tests/cowork/scenarios/no-key-skill-path.yaml +13 -0
  104. affinity_sdk-2.0.0/tests/cowork/scenarios/status-history.yaml +15 -0
  105. affinity_sdk-2.0.0/tests/cowork/sessions/no-key.yaml +6 -0
  106. affinity_sdk-2.0.0/tests/cowork/sessions/with-key.yaml +7 -0
  107. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/test_sdk_reads.py +8 -10
  108. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/test_sdk_writes.py +44 -69
  109. affinity_sdk-2.0.0/tests/test_api_coverage.py +162 -0
  110. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_config_cmds.py +24 -0
  111. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_csv_export.py +10 -10
  112. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_date_params.py +17 -14
  113. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_field_history.py +63 -0
  114. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_field_history_bulk.py +184 -15
  115. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_field_options_and_transcripts.py +1 -1
  116. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_list_cmds_coverage.py +13 -13
  117. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_list_expand_interactions.py +6 -6
  118. affinity_sdk-2.0.0/tests/test_cli_notes_writes.py +181 -0
  119. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_opportunity_cmds.py +1 -1
  120. affinity_sdk-2.0.0/tests/test_cli_plugin_manifest.py +23 -0
  121. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_pre_xaffinity_hook.py +51 -0
  122. affinity_sdk-2.0.0/tests/test_cli_reminders.py +253 -0
  123. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_session_setup_hook.py +38 -0
  124. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_set_phase_atomicity.py +50 -9
  125. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_v1_only_cmds.py +0 -195
  126. affinity_sdk-2.0.0/tests/test_cli_webhooks.py +212 -0
  127. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_write_ops.py +2 -2
  128. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_client.py +2 -2
  129. affinity_sdk-2.0.0/tests/test_files_v2.py +111 -0
  130. affinity_sdk-2.0.0/tests/test_lists_v2_writes.py +144 -0
  131. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_cli_version_check.py +29 -0
  132. affinity_sdk-2.0.0/tests/test_mcp_query_cli_error.py +75 -0
  133. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_models.py +1 -1
  134. affinity_sdk-2.0.0/tests/test_notes_v2_writes.py +300 -0
  135. affinity_sdk-2.0.0/tests/test_rate_limit_v2.py +78 -0
  136. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_readonly_factory.py +3 -2
  137. affinity_sdk-2.0.0/tests/test_reminder_list_batch.py +136 -0
  138. affinity_sdk-2.0.0/tests/test_reminders_v2.py +541 -0
  139. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_requirements_additional.py +4 -3
  140. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_lists_additional_coverage.py +22 -10
  141. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_rate_limits_coverage_gaps.py +18 -23
  142. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_v1_only_async.py +3 -119
  143. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_transport_and_readonly_mode.py +3 -2
  144. affinity_sdk-2.0.0/tests/test_v1_association_parsing.py +28 -0
  145. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_v1_only_services_additional_coverage.py +3 -63
  146. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_v1_only_services_more_coverage.py +0 -133
  147. affinity_sdk-2.0.0/tests/test_v2_request_bodies.py +271 -0
  148. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_validate_openapi_tool.py +33 -0
  149. affinity_sdk-2.0.0/tests/test_webhooks_v2.py +232 -0
  150. affinity_sdk-2.0.0/tools/api_coverage.json +1155 -0
  151. affinity_sdk-2.0.0/tools/api_coverage.py +238 -0
  152. affinity_sdk-2.0.0/tools/api_coverage_v1_snapshot.json +68 -0
  153. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/validate_openapi_models.py +37 -4
  154. affinity_sdk-1.28.0/docs/public/guides/api-versions-and-routing.md +0 -52
  155. affinity_sdk-1.28.0/docs/public/reference/services/v1/files.md +0 -3
  156. affinity_sdk-1.28.0/docs/public/reference/services/v1/notes.md +0 -3
  157. affinity_sdk-1.28.0/docs/public/reference/services/v1/reminders.md +0 -3
  158. affinity_sdk-1.28.0/docs/public/reference/services/v1/webhooks.md +0 -3
  159. affinity_sdk-1.28.0/mcp/.mcp-bash/VERSION +0 -1
  160. affinity_sdk-1.28.0/mcp/.mcp-bash/vendor.json +0 -1
  161. affinity_sdk-1.28.0/mcp/VERSION +0 -1
  162. affinity_sdk-1.28.0/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/setup.md +0 -58
  163. affinity_sdk-1.28.0/tests/test_reminder_list_batch.py +0 -184
  164. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.claude-plugin/marketplace.json +0 -0
  165. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.cursor/rules/test-data-privacy.mdc +0 -0
  166. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.editorconfig +0 -0
  167. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.env.example +0 -0
  168. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.gitattributes +0 -0
  169. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/CODEOWNERS +0 -0
  170. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  171. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  172. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/PULL_REQUEST_TEMPLATE/cli_command.md +0 -0
  173. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/PULL_REQUEST_TEMPLATE/release.md +0 -0
  174. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/dependabot.yml +0 -0
  175. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/labels.yml +0 -0
  176. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/mcp-release-install-footer.md +0 -0
  177. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/pull_request_template.md +0 -0
  178. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/release-install-footer.md +0 -0
  179. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/docs.yml +0 -0
  180. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/labels.yml +0 -0
  181. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/linkcheck.yml +0 -0
  182. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/openapi-validation.yml +0 -0
  183. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/plugin-release.yml +0 -0
  184. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/release-detect.yml +0 -0
  185. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/release.yml +0 -0
  186. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/.github/workflows/version-check.yml +0 -0
  187. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/AGENTS.md +0 -0
  188. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/CODE_OF_CONDUCT.md +0 -0
  189. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/CONTRIBUTING.md +0 -0
  190. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/LICENSE +0 -0
  191. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/SECURITY.md +0 -0
  192. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/VERSIONING.md +0 -0
  193. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/__init__.py +0 -0
  194. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/_internal/__init__.py +0 -0
  195. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/api_versions.py +0 -0
  196. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/__init__.py +0 -0
  197. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/__main__.py +0 -0
  198. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/_update_worker.py +0 -0
  199. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/click_compat.py +0 -0
  200. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/__init__.py +0 -0
  201. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_entity_field.py +0 -0
  202. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_entity_files_dump.py +0 -0
  203. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_entity_files_read.py +0 -0
  204. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_entity_files_upload.py +0 -0
  205. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_list_entry_fields.py +0 -0
  206. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_org_reads.py +0 -0
  207. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_search_common.py +0 -0
  208. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/_v1_parsing.py +0 -0
  209. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/company_cmds.py +0 -0
  210. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/completion_cmd.py +0 -0
  211. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/entry_cmds.py +0 -0
  212. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/file_cmds.py +0 -0
  213. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/file_url_cmd.py +0 -0
  214. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/interaction_cmds.py +0 -0
  215. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/opportunity_cmds.py +0 -0
  216. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/org_read_cmds.py +0 -0
  217. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/person_cmds.py +0 -0
  218. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/query_cmd.py +0 -0
  219. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/relationship_strength_cmds.py +0 -0
  220. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/resolve_url_cmd.py +0 -0
  221. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/session_cmds.py +0 -0
  222. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/task_cmds.py +0 -0
  223. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/transcript_cmds.py +0 -0
  224. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/version_cmd.py +0 -0
  225. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/commands/whoami_cmd.py +0 -0
  226. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/config.py +0 -0
  227. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/constants.py +0 -0
  228. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/context.py +0 -0
  229. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/csv_utils.py +0 -0
  230. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/date_utils.py +0 -0
  231. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/decorators.py +0 -0
  232. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/errors.py +0 -0
  233. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/field_utils.py +0 -0
  234. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/formatters.py +0 -0
  235. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/help_json.py +0 -0
  236. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/interaction_utils.py +0 -0
  237. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/logging.py +0 -0
  238. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/mcp_limits.py +0 -0
  239. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/options.py +0 -0
  240. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/paths.py +0 -0
  241. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/progress.py +0 -0
  242. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/__init__.py +0 -0
  243. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/aggregates.py +0 -0
  244. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/cursor.py +0 -0
  245. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/dates.py +0 -0
  246. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/exceptions.py +0 -0
  247. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/executor.py +0 -0
  248. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/filters.py +0 -0
  249. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/models.py +0 -0
  250. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/output.py +0 -0
  251. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/parser.py +0 -0
  252. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/planner.py +0 -0
  253. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/progress.py +0 -0
  254. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/query/schema.py +0 -0
  255. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/render.py +0 -0
  256. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/resolve.py +0 -0
  257. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/resolvers.py +0 -0
  258. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/results.py +0 -0
  259. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/runner.py +0 -0
  260. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/serialization.py +0 -0
  261. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/session_cache.py +0 -0
  262. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/types.py +0 -0
  263. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/cli/update_check.py +0 -0
  264. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/clients/__init__.py +0 -0
  265. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/clients/http.py +0 -0
  266. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/clients/pipeline.py +0 -0
  267. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/compare.py +0 -0
  268. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/downloads.py +0 -0
  269. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/exceptions.py +0 -0
  270. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/field_resolve_utils.py +0 -0
  271. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/field_resolver.py +0 -0
  272. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/filters.py +0 -0
  273. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/hooks.py +0 -0
  274. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/interactions_v2.py +0 -0
  275. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/pagination.py +0 -0
  276. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/rate_limit_snapshot.py +0 -0
  277. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/relationships_v2.py +0 -0
  278. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/search.py +0 -0
  279. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/models/transcripts.py +0 -0
  280. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/policies.py +0 -0
  281. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/progress.py +0 -0
  282. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/py.typed +0 -0
  283. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/_dropdown_options.py +0 -0
  284. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/_field_listing.py +0 -0
  285. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/_field_updates.py +0 -0
  286. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/_org_reads.py +0 -0
  287. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/companies.py +0 -0
  288. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/opportunities.py +0 -0
  289. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/persons.py +0 -0
  290. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/search.py +0 -0
  291. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/tasks.py +0 -0
  292. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/affinity/services/transcripts.py +0 -0
  293. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/codecov.yml +0 -0
  294. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/cli-development-guide.md +0 -0
  295. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/ai-integrations/index.md +0 -0
  296. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/changelog.md +0 -0
  297. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/cli/index.md +0 -0
  298. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/cli/scripting.md +0 -0
  299. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/cli-reference.md +0 -0
  300. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/examples.md +0 -0
  301. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/getting-started.md +0 -0
  302. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/glossary.md +0 -0
  303. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/affinity-official-mcp-comparison.md +0 -0
  304. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/api-versions.md +0 -0
  305. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/claude-code-plugins.md +0 -0
  306. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/configuration.md +0 -0
  307. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/csv-export.md +0 -0
  308. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/datetime-handling.md +0 -0
  309. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/debugging-hooks.md +0 -0
  310. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/field-types-and-values.md +0 -0
  311. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/field-values.md +0 -0
  312. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/filtering.md +0 -0
  313. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/ids-and-types.md +0 -0
  314. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/models.md +0 -0
  315. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/opportunity-associations.md +0 -0
  316. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/performance.md +0 -0
  317. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/query-command.md +0 -0
  318. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/rate-limits.md +0 -0
  319. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/guides/sync-vs-async.md +0 -0
  320. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/index.md +0 -0
  321. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/mcp/index.md +0 -0
  322. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/client.md +0 -0
  323. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/exceptions.md +0 -0
  324. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/filters.md +0 -0
  325. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/models.md +0 -0
  326. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/query-language.md +0 -0
  327. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/companies.md +0 -0
  328. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/lists.md +0 -0
  329. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/opportunities.md +0 -0
  330. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/persons.md +0 -0
  331. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/tasks.md +0 -0
  332. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/v1/auth.md +0 -0
  333. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/v1/field-values.md +0 -0
  334. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/v1/fields.md +0 -0
  335. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/v1/interactions.md +0 -0
  336. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/services/v1/relationships.md +0 -0
  337. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/reference/types.md +0 -0
  338. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/docs/public/troubleshooting.md +0 -0
  339. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/advanced_usage.py +0 -0
  340. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/async_lifecycle.py +0 -0
  341. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/basic_usage.py +0 -0
  342. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/filter_builder.py +0 -0
  343. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/hooks_debugging.py +0 -0
  344. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/list_management.py +0 -0
  345. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/resolve_helpers.py +0 -0
  346. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/examples/task_polling.py +0 -0
  347. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/.gitignore +0 -0
  348. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/skills/affinity-mcp-workflows/SKILL.md +0 -0
  349. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/skills/query-language/SKILL.md +0 -0
  350. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/skills/query-language/references/filter-operators.md +0 -0
  351. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/skills/query-language/references/include-expand.md +0 -0
  352. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/skills/query-language/references/output-formats.md +0 -0
  353. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/skills/query-language/references/quantifiers.md +0 -0
  354. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.claude-plugin/xaffinity-mcp.sh +0 -0
  355. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.gitignore +0 -0
  356. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/completion.sh +0 -0
  357. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/lifecycle.sh +0 -0
  358. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/logging.sh +0 -0
  359. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/ping.sh +0 -0
  360. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/prompts.sh +0 -0
  361. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/resources.sh +0 -0
  362. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/roots.sh +0 -0
  363. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/handlers/tools.sh +0 -0
  364. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/auth.sh +0 -0
  365. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/capabilities.sh +0 -0
  366. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/cli/health.sh +0 -0
  367. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/completion.sh +0 -0
  368. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/file_read.sh +0 -0
  369. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/handler_helpers.sh +0 -0
  370. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/hash.sh +0 -0
  371. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/ids.sh +0 -0
  372. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/io.sh +0 -0
  373. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/json.sh +0 -0
  374. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/lock.sh +0 -0
  375. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/logging.sh +0 -0
  376. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/meta_env.sh +0 -0
  377. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/paginate.sh +0 -0
  378. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/path.sh +0 -0
  379. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/policy.sh +0 -0
  380. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/progress-passthrough.sh +0 -0
  381. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/progress.sh +0 -0
  382. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/prompts.sh +0 -0
  383. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/registry.sh +0 -0
  384. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/require.sh +0 -0
  385. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/resource_content.sh +0 -0
  386. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/resource_match.sh +0 -0
  387. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/resource_providers.sh +0 -0
  388. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/resources.sh +0 -0
  389. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/roots.sh +0 -0
  390. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/rpc.sh +0 -0
  391. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/spec.sh +0 -0
  392. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/ui-templates.sh +0 -0
  393. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/ui.sh +0 -0
  394. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/uri.sh +0 -0
  395. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/lib/validate.sh +0 -0
  396. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/providers/echo.sh +0 -0
  397. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/providers/file.sh +0 -0
  398. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/providers/git.sh +0 -0
  399. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/providers/https.sh +0 -0
  400. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/providers/ui.sh +0 -0
  401. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.mcp-bash/sdk/ui-sdk.sh +0 -0
  402. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.registry/prompts.json +0 -0
  403. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.registry/resource-templates.json +0 -0
  404. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.registry/resources.json +0 -0
  405. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/.registry/ui-resources.json +0 -0
  406. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/Makefile +0 -0
  407. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/README.md +0 -0
  408. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/completions/entity-name.sh +0 -0
  409. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/completions/list-name.sh +0 -0
  410. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/completions/status-value.sh +0 -0
  411. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/docs/DEBUGGING.md +0 -0
  412. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/icon.svg +0 -0
  413. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/lib/cache.sh +0 -0
  414. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/lib/cli-detect.sh +0 -0
  415. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/lib/cli-gateway.sh +0 -0
  416. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/lib/common.sh +0 -0
  417. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/lib/entity-types.sh +0 -0
  418. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/lib/field-resolution.sh +0 -0
  419. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/mcp-publisher.lock +0 -0
  420. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/mcpb.conf +0 -0
  421. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/change-status/change-status.completion.sh +0 -0
  422. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/change-status/change-status.meta.json +0 -0
  423. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/change-status/change-status.txt +0 -0
  424. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/interaction-brief/interaction-brief.meta.json +0 -0
  425. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/interaction-brief/interaction-brief.txt +0 -0
  426. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/log-call/log-call.meta.json +0 -0
  427. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/log-call/log-call.txt +0 -0
  428. {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
  429. {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
  430. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/log-message/log-message.meta.json +0 -0
  431. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/log-message/log-message.txt +0 -0
  432. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/pipeline-review/pipeline-review.completion.sh +0 -0
  433. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/pipeline-review/pipeline-review.meta.json +0 -0
  434. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/pipeline-review/pipeline-review.txt +0 -0
  435. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/prepare-briefing/prepare-briefing.meta.json +0 -0
  436. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/prepare-briefing/prepare-briefing.txt +0 -0
  437. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/warm-intro/warm-intro.meta.json +0 -0
  438. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/prompts/warm-intro/warm-intro.txt +0 -0
  439. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/providers/xaffinity.sh +0 -0
  440. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/data-model/data-model.meta.json +0 -0
  441. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/field-catalogs/field-catalogs.meta.json +0 -0
  442. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/field-catalogs/field-catalogs.sh +0 -0
  443. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/interaction-enums/interaction-enums.json +0 -0
  444. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/interaction-enums/interaction-enums.meta.json +0 -0
  445. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/me/me.meta.json +0 -0
  446. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/me/me.sh +0 -0
  447. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/me-person-id/me-person-id.meta.json +0 -0
  448. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/me-person-id/me-person-id.sh +0 -0
  449. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/query-guide/query-guide.meta.json +0 -0
  450. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/query-guide/query-guide.sh +0 -0
  451. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/saved-views/saved-views.meta.json +0 -0
  452. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/saved-views/saved-views.sh +0 -0
  453. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/workflow-config/workflow-config.meta.json +0 -0
  454. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/workflow-config/workflow-config.sh +0 -0
  455. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/workflows-guide/workflows-guide.meta.json +0 -0
  456. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/workflows-guide/workflows-guide.sh +0 -0
  457. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/xaffinity-field-catalogs.completion.sh +0 -0
  458. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/xaffinity-saved-views.completion.sh +0 -0
  459. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/resources/xaffinity-workflow-config.completion.sh +0 -0
  460. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/server.d/env.sh +0 -0
  461. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/server.d/health-checks.sh +0 -0
  462. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/server.json +0 -0
  463. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/test/README.md +0 -0
  464. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/test/test_env_update_check.sh +0 -0
  465. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/test-progress.sh +0 -0
  466. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/discover-commands/tool.meta.json +0 -0
  467. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/discover-commands/tool.sh +0 -0
  468. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/execute-read-command/tool.meta.json +0 -0
  469. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/execute-read-command/tool.sh +0 -0
  470. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/get-entity-dossier/tool.meta.json +0 -0
  471. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/get-entity-dossier/tool.sh +0 -0
  472. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/get-file-url/tool.meta.json +0 -0
  473. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/get-file-url/tool.sh +0 -0
  474. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/query/tool.meta.json +0 -0
  475. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/read-xaffinity-resource/tool.meta.json +0 -0
  476. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/tools/read-xaffinity-resource/tool.sh +0 -0
  477. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/user-config.json +0 -0
  478. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/xaffinity-mcp-env.sh +0 -0
  479. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/mcp/xaffinity-mcp.sh +0 -0
  480. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/hooks/hooks.json +0 -0
  481. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/files-and-writes.md +0 -0
  482. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/filtering.md +0 -0
  483. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/interactions.md +0 -0
  484. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/query-guide.md +0 -0
  485. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/query/test_cursor.py +0 -0
  486. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_company_create_dedup.py +0 -0
  487. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_company_ls_filter_rejection.py +0 -0
  488. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_formatters.py +0 -0
  489. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_output_formats_integration.py +0 -0
  490. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_person_create_dedup.py +0 -0
  491. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_person_ls_filter_rejection.py +0 -0
  492. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_query_filter_rejection.py +0 -0
  493. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_query_list_entry_relationships.py +0 -0
  494. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_query_list_export_parity.py +0 -0
  495. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_query_output_flattening.py +0 -0
  496. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_query_output_truncation.py +0 -0
  497. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/cli/test_query_unreplied.py +0 -0
  498. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/conftest.py +0 -0
  499. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/field_write_mocks.py +0 -0
  500. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/fixtures/openapi/mini_openapi.json +0 -0
  501. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/fixtures/webhooks/field_value_updated.json +0 -0
  502. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/fixtures/webhooks/list_entry_created.json +0 -0
  503. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/fixtures/webhooks/organization_created.json +0 -0
  504. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/fixtures/webhooks/organization_merged.json +0 -0
  505. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/fixtures/webhooks/person_created.json +0 -0
  506. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/fixtures/webhooks/unknown_event.json +0 -0
  507. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/README.md +0 -0
  508. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/conftest.py +0 -0
  509. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/setup_query_parity_data.py +0 -0
  510. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/test_cli_writes.py +0 -0
  511. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/test_query_parity_integration.py +0 -0
  512. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/integration/test_sdk_writes_runner.py +0 -0
  513. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/mcp/__init__.py +0 -0
  514. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/mcp/test_query_cursor.py +0 -0
  515. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/skill-evals/xaffinity-cli-usage-evals/evals.json +0 -0
  516. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/spec_guard.py +0 -0
  517. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_affinity_client_wrapper_additional_coverage.py +0 -0
  518. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_api_key_file_formats.py +0 -0
  519. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_api_key_resolution.py +0 -0
  520. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_api_version.py +0 -0
  521. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_api_version_per_operation.py +0 -0
  522. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_async_file_download_streaming.py +0 -0
  523. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_batch_get.py +0 -0
  524. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_api_version.py +0 -0
  525. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_column_limiting.py +0 -0
  526. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_command_context.py +0 -0
  527. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_company_cmds_coverage.py +0 -0
  528. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_company_get.py +0 -0
  529. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_context_coverage.py +0 -0
  530. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_date_utils.py +0 -0
  531. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_datetime_formatting.py +0 -0
  532. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_datetime_header_offsets.py +0 -0
  533. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_domain_linkification.py +0 -0
  534. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_dotenv_resolution.py +0 -0
  535. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_dropdown_field_writes.py +0 -0
  536. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_enriched_field_writes.py +0 -0
  537. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_entity_field_writes.py +0 -0
  538. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_entity_files_dump.py +0 -0
  539. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_entry_field.py +0 -0
  540. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_entry_field_batch_writes.py +0 -0
  541. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_entry_field_multi_value_limits.py +0 -0
  542. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_error_hints.py +0 -0
  543. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_error_rendering.py +0 -0
  544. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_field_utils.py +0 -0
  545. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_field_utils_coverage.py +0 -0
  546. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_field_utils_set_phase.py +0 -0
  547. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_field_value_humanization.py +0 -0
  548. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_file_url.py +0 -0
  549. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_files_ls.py +0 -0
  550. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_files_read.py +0 -0
  551. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_get_interaction_dates.py +0 -0
  552. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_help_json.py +0 -0
  553. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_interaction_date_chunking.py +0 -0
  554. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_interaction_utils.py +0 -0
  555. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_json_safety.py +0 -0
  556. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_list_export_entity_scope.py +0 -0
  557. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_list_export_field_refresh.py +0 -0
  558. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_list_export_filter_safety.py +0 -0
  559. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_list_export_truncation_meta.py +0 -0
  560. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_missing_coverage.py +0 -0
  561. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_multi_value_truncation_warnings.py +0 -0
  562. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_no_network_commands.py +0 -0
  563. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_opportunity_cmds_coverage.py +0 -0
  564. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_pager_logic.py +0 -0
  565. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_person_cmds_coverage.py +0 -0
  566. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_person_get.py +0 -0
  567. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_progress_manager.py +0 -0
  568. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_aggregates.py +0 -0
  569. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_cmd.py +0 -0
  570. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_cmd_coverage.py +0 -0
  571. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_dates.py +0 -0
  572. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_executor.py +0 -0
  573. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_expand_interactions.py +0 -0
  574. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_filters.py +0 -0
  575. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_integration.py +0 -0
  576. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_parser.py +0 -0
  577. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_planner.py +0 -0
  578. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_safety.py +0 -0
  579. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_query_schema.py +0 -0
  580. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_rate_limit_rendering.py +0 -0
  581. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_rate_limit_throttle.py +0 -0
  582. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_render_coverage.py +0 -0
  583. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_resolve_coverage.py +0 -0
  584. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_resolve_url_parsing.py +0 -0
  585. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_result_summary.py +0 -0
  586. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_safe_field_writes.py +0 -0
  587. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_search.py +0 -0
  588. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_serialization.py +0 -0
  589. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_session_cache.py +0 -0
  590. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_types.py +0 -0
  591. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_unreplied.py +0 -0
  592. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_update_check.py +0 -0
  593. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_cli_v1_parsing.py +0 -0
  594. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_companies_create_dedup.py +0 -0
  595. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_companies_filter_rejection.py +0 -0
  596. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_compare.py +0 -0
  597. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_env_helpers.py +0 -0
  598. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_exceptions_coverage.py +0 -0
  599. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_field_resolver.py +0 -0
  600. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_field_service_caching.py +0 -0
  601. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_field_types_c4.py +0 -0
  602. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_field_value_type.py +0 -0
  603. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_field_values_get_value.py +0 -0
  604. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_file_batch_get.py +0 -0
  605. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_file_download_streaming.py +0 -0
  606. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_file_list_batch.py +0 -0
  607. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_file_upload_helpers_and_validation.py +0 -0
  608. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_files_upload_returning_files.py +0 -0
  609. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_filters.py +0 -0
  610. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_generate_mcp_command_registry.py +0 -0
  611. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_get_fields_filter_includes.py +0 -0
  612. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_get_fields_pagination.py +0 -0
  613. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_get_first.py +0 -0
  614. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_hidden_field_values.py +0 -0
  615. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_hooks.py +0 -0
  616. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_http_client_additional_coverage.py +0 -0
  617. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_http_client_remaining_coverage.py +0 -0
  618. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_inbound_webhooks.py +0 -0
  619. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_integration_smoke.py +0 -0
  620. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_interaction_date_validation.py +0 -0
  621. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_interactions_and_files_regressions.py +0 -0
  622. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_isodatetime.py +0 -0
  623. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_list_entry_membership_and_opportunities.py +0 -0
  624. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_list_term.py +0 -0
  625. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_bundle_env_and_completions.py +0 -0
  626. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_entity_dossier.py +0 -0
  627. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_gateway_limits.py +0 -0
  628. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_history_bulk_gateway.py +0 -0
  629. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_limits.py +0 -0
  630. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_read_truncation.py +0 -0
  631. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_mcp_resource_scripts.py +0 -0
  632. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_models_v2_2026_fields.py +0 -0
  633. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_multi_value_limits.py +0 -0
  634. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_new_features.py +0 -0
  635. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_notes_v2.py +0 -0
  636. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_opportunities_filter_rejection.py +0 -0
  637. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_org_reads.py +0 -0
  638. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_pagination_iterators.py +0 -0
  639. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_persons_create_dedup.py +0 -0
  640. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_persons_filter_rejection.py +0 -0
  641. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_public_api.py +0 -0
  642. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_raw_pipeline_hook_events.py +0 -0
  643. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_sdk_interaction_dates.py +0 -0
  644. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_search.py +0 -0
  645. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_service_get_parameter_combinations.py +0 -0
  646. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_companies_coverage_gaps.py +0 -0
  647. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_dropdown_options.py +0 -0
  648. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_entity_field_updates.py +0 -0
  649. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_field_value_changes.py +0 -0
  650. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_list_entries_filter_paths.py +0 -0
  651. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_lists_coverage_gaps.py +0 -0
  652. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_opportunities_additional_coverage.py +0 -0
  653. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_opportunities_coverage_gaps.py +0 -0
  654. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_opportunities_tasks_additional_coverage.py +0 -0
  655. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_persons_companies_additional_coverage.py +0 -0
  656. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_services_v1_only_coverage_gaps.py +0 -0
  657. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_small_modules_coverage.py +0 -0
  658. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/test_spec_guard.py +0 -0
  659. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/unit/__init__.py +0 -0
  660. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tests/unit/test_exceptions.py +0 -0
  661. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/__init__.py +0 -0
  662. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/check_cli_patterns.py +0 -0
  663. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/generate_mcp_command_registry.py +0 -0
  664. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/generate_release_notes.py +0 -0
  665. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/generate_requirements_mapping.py +0 -0
  666. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/openapi_snapshots/2024-01-01.json +0 -0
  667. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/openapi_snapshots/2026-07-15.json +0 -0
  668. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/openapi_snapshots/2026-09-17.json +0 -0
  669. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/sync_mcp_bundle_env.py +0 -0
  670. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/sync_mcp_registry.py +0 -0
  671. {affinity_sdk-1.28.0 → affinity_sdk-2.0.0}/tools/sync_mcp_version.py +0 -0
  672. {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
 
@@ -68,3 +68,6 @@ dormant_founders.json
68
68
  docs/superpowers/
69
69
 
70
70
  uv.lock
71
+
72
+ # cowork-harness test image build output
73
+ tests/cowork/image/dist/
@@ -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`) accept a
15
- `.env` file and a named pipe, so a 1Password Environments locally mounted `.env` works directly:
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 mount: approval and unlock prompts, repeated and
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`s; forced `--strategy field` never falls back.
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: 1.28.0
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 subscription
470
+ # Create a webhook (subscriptions is required; [] means every event type)
463
471
  webhook = client.webhooks.create(
464
472
  WebhookCreate(
465
- webhook_url="https://your-server.com/webhook",
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
- # List all webhooks (max 3 per instance)
475
- webhooks = client.webhooks.list()
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
- # Disable a webhook
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 | ✅ | ✅ | V1 |
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-only services like notes/reminders/webhooks/files).
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 subscription
409
+ # Create a webhook (subscriptions is required; [] means every event type)
402
410
  webhook = client.webhooks.create(
403
411
  WebhookCreate(
404
- webhook_url="https://your-server.com/webhook",
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
- # List all webhooks (max 3 per instance)
414
- webhooks = client.webhooks.list()
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
- # Disable a webhook
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 | ✅ | ✅ | V1 |
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-only services like notes/reminders/webhooks/files).
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 mounted .env).
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 was the read approved?"
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 here: reading it asks
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
- pattern = "xaffinity --dotenv --readonly <command> --json"
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 prompt the user).
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"