affinity-sdk 0.9.2__tar.gz → 0.9.11__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 (406) hide show
  1. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/workflows/plugin-release.yml +29 -18
  2. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/workflows/release-detect.yml +53 -16
  3. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/workflows/release.yml +87 -32
  4. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.gitignore +1 -0
  5. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/CHANGELOG.md +143 -0
  6. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/PKG-INFO +1 -1
  7. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/VERSIONING.md +8 -1
  8. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/__init__.py +4 -0
  9. affinity_sdk-0.9.11/affinity/cli/__main__.py +6 -0
  10. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/_entity_files_dump.py +2 -2
  11. affinity_sdk-0.9.11/affinity/cli/commands/_v1_parsing.py +186 -0
  12. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/company_cmds.py +42 -21
  13. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/interaction_cmds.py +1 -1
  14. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/list_cmds.py +319 -84
  15. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/note_cmds.py +10 -5
  16. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/opportunity_cmds.py +29 -35
  17. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/person_cmds.py +46 -9
  18. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/query_cmd.py +100 -5
  19. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/reminder_cmds.py +75 -17
  20. affinity_sdk-0.9.11/affinity/cli/constants.py +16 -0
  21. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/context.py +2 -1
  22. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/csv_utils.py +7 -17
  23. affinity_sdk-0.9.11/affinity/cli/formatters.py +659 -0
  24. affinity_sdk-0.9.11/affinity/cli/interaction_utils.py +460 -0
  25. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/options.py +9 -2
  26. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/query/aggregates.py +12 -4
  27. affinity_sdk-0.9.11/affinity/cli/query/executor.py +2455 -0
  28. affinity_sdk-0.9.11/affinity/cli/query/filters.py +808 -0
  29. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/query/models.py +103 -3
  30. affinity_sdk-0.9.11/affinity/cli/query/output.py +900 -0
  31. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/query/parser.py +48 -6
  32. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/query/planner.py +302 -22
  33. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/query/schema.py +96 -3
  34. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/runner.py +80 -25
  35. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/clients/http.py +2 -2
  36. affinity_sdk-0.9.11/affinity/compare.py +501 -0
  37. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/filters.py +425 -37
  38. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/models/entities.py +14 -4
  39. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/models/pagination.py +55 -14
  40. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/models/types.py +19 -8
  41. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/services/companies.py +384 -50
  42. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/services/lists.py +234 -45
  43. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/services/opportunities.py +153 -60
  44. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/services/persons.py +456 -44
  45. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/services/v1_only.py +275 -19
  46. affinity_sdk-0.9.11/codecov.yml +25 -0
  47. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/cli-development-guide.md +2 -2
  48. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/cli/commands.md +44 -0
  49. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/cli/scripting.md +85 -1
  50. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/cli-reference.md +25 -2
  51. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/api-versions-and-routing.md +4 -0
  52. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/errors-and-retries.md +55 -1
  53. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/filtering.md +96 -33
  54. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/pagination.md +37 -2
  55. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/performance.md +43 -0
  56. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/query-command.md +98 -3
  57. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/query-language.md +281 -27
  58. affinity_sdk-0.9.11/docs/public/reference/services/companies.md +47 -0
  59. affinity_sdk-0.9.11/docs/public/reference/services/persons.md +42 -0
  60. affinity_sdk-0.9.11/docs/public/troubleshooting.md +58 -0
  61. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/.claude-plugin/plugin.json +1 -1
  62. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/.claude-plugin/skills/affinity-mcp-workflows/SKILL.md +13 -4
  63. affinity_sdk-0.9.11/mcp/.claude-plugin/skills/query-language/SKILL.md +721 -0
  64. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/.registry/commands-metadata.json +23 -8
  65. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/.registry/commands.json +100 -30
  66. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/.registry/prompts.json +1 -1
  67. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/.registry/resource-templates.json +3 -3
  68. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/.registry/resources.json +2 -2
  69. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/CHANGELOG.md +89 -0
  70. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/COMPATIBILITY +21 -1
  71. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/README.md +125 -16
  72. affinity_sdk-0.9.11/mcp/VERSION +1 -0
  73. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/docs/DEBUGGING.md +8 -7
  74. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/lib/common.sh +50 -9
  75. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/mcp-bash.lock +2 -2
  76. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/resources/data-model/data-model.md +55 -6
  77. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/resources/field-catalogs/field-catalogs.meta.json +1 -1
  78. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/resources/field-catalogs/field-catalogs.sh +26 -11
  79. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/scripts/install-framework.sh +1 -1
  80. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/server.d/requirements.json +1 -1
  81. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/server.d/server.meta.json +1 -1
  82. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/test/README.md +3 -3
  83. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/test/run.sh +46 -0
  84. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/tools/execute-read-command/tool.meta.json +6 -0
  85. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/tools/execute-read-command/tool.sh +27 -7
  86. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/tools/execute-write-command/tool.sh +27 -7
  87. affinity_sdk-0.9.11/mcp/tools/query/tool.meta.json +105 -0
  88. affinity_sdk-0.9.11/mcp/tools/query/tool.sh +139 -0
  89. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mkdocs.yml +2 -0
  90. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/plugins/affinity-sdk/.claude-plugin/plugin.json +1 -1
  91. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/plugins/xaffinity-cli/.claude-plugin/plugin.json +1 -1
  92. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/pyproject.toml +3 -2
  93. affinity_sdk-0.9.11/tests/cli/test_formatters.py +757 -0
  94. affinity_sdk-0.9.11/tests/cli/test_output_formats_integration.py +376 -0
  95. affinity_sdk-0.9.11/tests/cli/test_query_output_truncation.py +685 -0
  96. affinity_sdk-0.9.11/tests/integration/README.md +155 -0
  97. affinity_sdk-0.9.11/tests/integration/conftest.py +122 -0
  98. affinity_sdk-0.9.11/tests/integration/test_cli_writes.py +594 -0
  99. affinity_sdk-0.9.11/tests/integration/test_sdk_reads.py +470 -0
  100. affinity_sdk-0.9.11/tests/integration/test_sdk_writes.py +1767 -0
  101. affinity_sdk-0.9.11/tests/integration/test_sdk_writes_runner.py +225 -0
  102. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_company_get.py +25 -22
  103. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_csv_export.py +44 -25
  104. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_entity_files_dump.py +1 -0
  105. affinity_sdk-0.9.11/tests/test_cli_get_interaction_dates.py +262 -0
  106. affinity_sdk-0.9.11/tests/test_cli_interaction_utils.py +351 -0
  107. affinity_sdk-0.9.11/tests/test_cli_list_expand_interactions.py +332 -0
  108. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_opportunity_cmds.py +60 -49
  109. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_query_aggregates.py +26 -0
  110. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_query_cmd.py +56 -27
  111. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_query_executor.py +1477 -44
  112. affinity_sdk-0.9.11/tests/test_cli_query_expand_interactions.py +793 -0
  113. affinity_sdk-0.9.11/tests/test_cli_query_filters.py +1616 -0
  114. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_query_integration.py +153 -0
  115. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_query_parser.py +1 -1
  116. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_query_planner.py +408 -0
  117. affinity_sdk-0.9.11/tests/test_cli_query_safety.py +258 -0
  118. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_query_schema.py +2 -2
  119. affinity_sdk-0.9.11/tests/test_cli_unreplied_email.py +244 -0
  120. affinity_sdk-0.9.11/tests/test_cli_v1_parsing.py +195 -0
  121. affinity_sdk-0.9.11/tests/test_compare.py +518 -0
  122. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_field_value_type.py +3 -2
  123. affinity_sdk-0.9.11/tests/test_filters.py +1071 -0
  124. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_models.py +5 -2
  125. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_requirements_additional.py +2 -2
  126. affinity_sdk-0.9.11/tests/test_sdk_interaction_dates.py +600 -0
  127. affinity_sdk-0.9.11/tests/test_service_get_parameter_combinations.py +339 -0
  128. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_services_lists_additional_coverage.py +10 -3
  129. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_services_opportunities_additional_coverage.py +82 -16
  130. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_services_persons_companies_additional_coverage.py +476 -52
  131. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_small_modules_coverage.py +54 -4
  132. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_v1_only_services_more_coverage.py +1 -1
  133. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/uv.lock +1 -1
  134. affinity_sdk-0.9.2/affinity/cli/commands/_v1_parsing.py +0 -77
  135. affinity_sdk-0.9.2/affinity/cli/query/executor.py +0 -1222
  136. affinity_sdk-0.9.2/affinity/cli/query/filters.py +0 -330
  137. affinity_sdk-0.9.2/affinity/cli/query/output.py +0 -271
  138. affinity_sdk-0.9.2/docs/public/reference/services/companies.md +0 -10
  139. affinity_sdk-0.9.2/docs/public/reference/services/persons.md +0 -5
  140. affinity_sdk-0.9.2/docs/public/troubleshooting.md +0 -22
  141. affinity_sdk-0.9.2/mcp/.claude-plugin/skills/query-language/SKILL.md +0 -381
  142. affinity_sdk-0.9.2/mcp/VERSION +0 -1
  143. affinity_sdk-0.9.2/mcp/tools/query/tool.meta.json +0 -94
  144. affinity_sdk-0.9.2/mcp/tools/query/tool.sh +0 -115
  145. affinity_sdk-0.9.2/tests/test_cli_query_filters.py +0 -538
  146. affinity_sdk-0.9.2/tests/test_filters.py +0 -390
  147. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.claude-plugin/marketplace.json +0 -0
  148. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.editorconfig +0 -0
  149. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.env.example +0 -0
  150. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.gitattributes +0 -0
  151. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/CODEOWNERS +0 -0
  152. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  153. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  154. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/PULL_REQUEST_TEMPLATE/cli_command.md +0 -0
  155. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/PULL_REQUEST_TEMPLATE/release.md +0 -0
  156. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/dependabot.yml +0 -0
  157. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/labels.yml +0 -0
  158. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/pull_request_template.md +0 -0
  159. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/workflows/ci.yml +0 -0
  160. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/workflows/docs.yml +0 -0
  161. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/workflows/labels.yml +0 -0
  162. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/workflows/linkcheck.yml +0 -0
  163. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/workflows/openapi-validation.yml +0 -0
  164. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/workflows/plugin-build.yml +0 -0
  165. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.github/workflows/version-check.yml +0 -0
  166. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/.pre-commit-config.yaml +0 -0
  167. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/CODE_OF_CONDUCT.md +0 -0
  168. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/CONTRIBUTING.md +0 -0
  169. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/LICENSE +0 -0
  170. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/README.md +0 -0
  171. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/SECURITY.md +0 -0
  172. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/__init__.py +0 -0
  173. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/click_compat.py +0 -0
  174. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/__init__.py +0 -0
  175. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/_list_entry_fields.py +0 -0
  176. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/completion_cmd.py +0 -0
  177. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/config_cmds.py +0 -0
  178. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/entry_cmds.py +0 -0
  179. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/field_cmds.py +0 -0
  180. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/relationship_strength_cmds.py +0 -0
  181. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/resolve_url_cmd.py +0 -0
  182. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/session_cmds.py +0 -0
  183. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/task_cmds.py +0 -0
  184. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/version_cmd.py +0 -0
  185. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/commands/whoami_cmd.py +0 -0
  186. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/config.py +0 -0
  187. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/date_utils.py +0 -0
  188. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/decorators.py +0 -0
  189. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/errors.py +0 -0
  190. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/field_utils.py +0 -0
  191. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/help_json.py +0 -0
  192. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/logging.py +0 -0
  193. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/main.py +0 -0
  194. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/paths.py +0 -0
  195. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/progress.py +0 -0
  196. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/query/__init__.py +0 -0
  197. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/query/dates.py +0 -0
  198. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/query/exceptions.py +0 -0
  199. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/query/progress.py +0 -0
  200. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/render.py +0 -0
  201. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/resolve.py +0 -0
  202. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/resolvers.py +0 -0
  203. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/results.py +0 -0
  204. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/serialization.py +0 -0
  205. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/session_cache.py +0 -0
  206. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/cli/types.py +0 -0
  207. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/client.py +0 -0
  208. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/clients/__init__.py +0 -0
  209. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/clients/pipeline.py +0 -0
  210. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/downloads.py +0 -0
  211. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/exceptions.py +0 -0
  212. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/hooks.py +0 -0
  213. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/inbound_webhooks.py +0 -0
  214. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/models/__init__.py +0 -0
  215. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/models/rate_limit_snapshot.py +0 -0
  216. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/models/secondary.py +0 -0
  217. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/policies.py +0 -0
  218. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/progress.py +0 -0
  219. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/py.typed +0 -0
  220. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/services/__init__.py +0 -0
  221. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/services/rate_limits.py +0 -0
  222. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/services/tasks.py +0 -0
  223. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/affinity/types.py +0 -0
  224. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/ai-integrations/index.md +0 -0
  225. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/changelog.md +0 -0
  226. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/cli/index.md +0 -0
  227. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/examples.md +0 -0
  228. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/getting-started.md +0 -0
  229. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/glossary.md +0 -0
  230. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/authentication.md +0 -0
  231. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/claude-code-plugins.md +0 -0
  232. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/configuration.md +0 -0
  233. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/csv-export.md +0 -0
  234. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/datetime-handling.md +0 -0
  235. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/debugging-hooks.md +0 -0
  236. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/field-types-and-values.md +0 -0
  237. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/field-values.md +0 -0
  238. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/ids-and-types.md +0 -0
  239. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/models.md +0 -0
  240. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/opportunity-associations.md +0 -0
  241. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/rate-limits.md +0 -0
  242. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/sync-vs-async.md +0 -0
  243. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/guides/webhooks.md +0 -0
  244. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/index.md +0 -0
  245. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/mcp/index.md +0 -0
  246. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/client.md +0 -0
  247. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/exceptions.md +0 -0
  248. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/filters.md +0 -0
  249. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/models.md +0 -0
  250. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/services/lists.md +0 -0
  251. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/services/opportunities.md +0 -0
  252. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/services/tasks.md +0 -0
  253. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/services/v1/auth.md +0 -0
  254. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/services/v1/field-values.md +0 -0
  255. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/services/v1/fields.md +0 -0
  256. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/services/v1/files.md +0 -0
  257. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/services/v1/interactions.md +0 -0
  258. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/services/v1/notes.md +0 -0
  259. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/services/v1/relationships.md +0 -0
  260. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/services/v1/reminders.md +0 -0
  261. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/services/v1/webhooks.md +0 -0
  262. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/docs/public/reference/types.md +0 -0
  263. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/examples/advanced_usage.py +0 -0
  264. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/examples/async_lifecycle.py +0 -0
  265. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/examples/basic_usage.py +0 -0
  266. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/examples/filter_builder.py +0 -0
  267. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/examples/hooks_debugging.py +0 -0
  268. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/examples/list_management.py +0 -0
  269. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/examples/resolve_helpers.py +0 -0
  270. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/examples/task_polling.py +0 -0
  271. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/.claude-plugin/.gitignore +0 -0
  272. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/.claude-plugin/.mcp.json +0 -0
  273. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/.claude-plugin/xaffinity-mcp.sh +0 -0
  274. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/.gitignore +0 -0
  275. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/Makefile +0 -0
  276. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/completions/entity-name.sh +0 -0
  277. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/completions/list-name.sh +0 -0
  278. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/completions/status-value.sh +0 -0
  279. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/docs/internal/debugging-improvements-plan.md +0 -0
  280. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/docs/internal/mcp-bash-progress-timeout-feature-request.md +0 -0
  281. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/icon.svg +0 -0
  282. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/lib/cache.sh +0 -0
  283. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/lib/cli-gateway.sh +0 -0
  284. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/lib/entity-types.sh +0 -0
  285. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/lib/field-resolution.sh +0 -0
  286. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/mcpb.conf +0 -0
  287. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/change-status/change-status.meta.json +0 -0
  288. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/change-status/change-status.txt +0 -0
  289. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/interaction-brief/interaction-brief.meta.json +0 -0
  290. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/interaction-brief/interaction-brief.txt +0 -0
  291. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/log-call/log-call.meta.json +0 -0
  292. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/log-call/log-call.txt +0 -0
  293. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/log-interaction-and-update-workflow/log-interaction-and-update-workflow.meta.json +0 -0
  294. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/log-interaction-and-update-workflow/log-interaction-and-update-workflow.txt +0 -0
  295. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/log-message/log-message.meta.json +0 -0
  296. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/log-message/log-message.txt +0 -0
  297. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/pipeline-review/pipeline-review.meta.json +0 -0
  298. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/pipeline-review/pipeline-review.txt +0 -0
  299. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/prepare-briefing/prepare-briefing.meta.json +0 -0
  300. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/prepare-briefing/prepare-briefing.txt +0 -0
  301. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/warm-intro/warm-intro.meta.json +0 -0
  302. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/prompts/warm-intro/warm-intro.txt +0 -0
  303. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/providers/xaffinity.sh +0 -0
  304. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/resources/data-model/data-model.meta.json +0 -0
  305. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/resources/interaction-enums/interaction-enums.json +0 -0
  306. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/resources/interaction-enums/interaction-enums.meta.json +0 -0
  307. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/resources/me/me.meta.json +0 -0
  308. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/resources/me/me.sh +0 -0
  309. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/resources/me-person-id/me-person-id.meta.json +0 -0
  310. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/resources/me-person-id/me-person-id.sh +0 -0
  311. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/resources/saved-views/saved-views.meta.json +0 -0
  312. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/resources/saved-views/saved-views.sh +0 -0
  313. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/resources/workflow-config/workflow-config.meta.json +0 -0
  314. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/resources/workflow-config/workflow-config.sh +0 -0
  315. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/server.d/env.sh +0 -0
  316. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/server.d/health-checks.sh +0 -0
  317. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/server.d/policy.sh +0 -0
  318. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/test-progress.sh +0 -0
  319. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/tools/discover-commands/tool.meta.json +0 -0
  320. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/tools/discover-commands/tool.sh +0 -0
  321. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/tools/execute-write-command/tool.meta.json +0 -0
  322. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/tools/get-entity-dossier/tool.meta.json +0 -0
  323. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/tools/get-entity-dossier/tool.sh +0 -0
  324. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/tools/read-xaffinity-resource/tool.meta.json +0 -0
  325. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/tools/read-xaffinity-resource/tool.sh +0 -0
  326. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/xaffinity-mcp-env.sh +0 -0
  327. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/mcp/xaffinity-mcp.sh +0 -0
  328. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/plugins/affinity-sdk/.claude-plugin/skills/affinity-python-sdk/SKILL.md +0 -0
  329. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/plugins/xaffinity-cli/.claude-plugin/commands/affinity-help.md +0 -0
  330. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/plugins/xaffinity-cli/.claude-plugin/hooks/hooks.json +0 -0
  331. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/plugins/xaffinity-cli/.claude-plugin/hooks/pre-xaffinity.sh +0 -0
  332. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/plugins/xaffinity-cli/.claude-plugin/skills/xaffinity-cli-usage/SKILL.md +0 -0
  333. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/conftest.py +0 -0
  334. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/fixtures/webhooks/field_value_updated.json +0 -0
  335. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/fixtures/webhooks/list_entry_created.json +0 -0
  336. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/fixtures/webhooks/organization_created.json +0 -0
  337. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/fixtures/webhooks/organization_merged.json +0 -0
  338. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/fixtures/webhooks/person_created.json +0 -0
  339. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/fixtures/webhooks/unknown_event.json +0 -0
  340. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_affinity_client_wrapper_additional_coverage.py +0 -0
  341. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_async_file_download_streaming.py +0 -0
  342. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_column_limiting.py +0 -0
  343. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_command_context.py +0 -0
  344. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_company_cmds_coverage.py +0 -0
  345. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_config_cmds.py +0 -0
  346. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_date_params.py +0 -0
  347. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_date_utils.py +0 -0
  348. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_datetime_formatting.py +0 -0
  349. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_datetime_header_offsets.py +0 -0
  350. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_domain_linkification.py +0 -0
  351. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_entry_field.py +0 -0
  352. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_error_rendering.py +0 -0
  353. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_field_history.py +0 -0
  354. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_field_value_humanization.py +0 -0
  355. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_interaction_date_chunking.py +0 -0
  356. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_json_safety.py +0 -0
  357. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_list_cmds_coverage.py +0 -0
  358. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_missing_coverage.py +0 -0
  359. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_no_network_commands.py +0 -0
  360. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_opportunity_cmds_coverage.py +0 -0
  361. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_pager_logic.py +0 -0
  362. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_person_cmds_coverage.py +0 -0
  363. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_person_get.py +0 -0
  364. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_progress_manager.py +0 -0
  365. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_query_dates.py +0 -0
  366. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_rate_limit_rendering.py +0 -0
  367. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_resolve_url_parsing.py +0 -0
  368. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_result_summary.py +0 -0
  369. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_serialization.py +0 -0
  370. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_session_cache.py +0 -0
  371. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_types.py +0 -0
  372. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_v1_only_cmds.py +0 -0
  373. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_cli_write_ops.py +0 -0
  374. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_client.py +0 -0
  375. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_env_helpers.py +0 -0
  376. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_exceptions_coverage.py +0 -0
  377. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_file_download_streaming.py +0 -0
  378. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_file_upload_helpers_and_validation.py +0 -0
  379. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_hooks.py +0 -0
  380. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_http_client_additional_coverage.py +0 -0
  381. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_http_client_remaining_coverage.py +0 -0
  382. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_inbound_webhooks.py +0 -0
  383. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_integration_smoke.py +0 -0
  384. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_interactions_and_files_regressions.py +0 -0
  385. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_isodatetime.py +0 -0
  386. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_list_entry_membership_and_opportunities.py +0 -0
  387. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_new_features.py +0 -0
  388. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_pagination_iterators.py +0 -0
  389. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_public_api.py +0 -0
  390. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_raw_pipeline_hook_events.py +0 -0
  391. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_services_companies_coverage_gaps.py +0 -0
  392. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_services_lists_coverage_gaps.py +0 -0
  393. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_services_opportunities_coverage_gaps.py +0 -0
  394. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_services_opportunities_tasks_additional_coverage.py +0 -0
  395. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_services_rate_limits_coverage_gaps.py +0 -0
  396. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_services_v1_only_async.py +0 -0
  397. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_services_v1_only_coverage_gaps.py +0 -0
  398. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_transport_and_readonly_mode.py +0 -0
  399. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tests/test_v1_only_services_additional_coverage.py +0 -0
  400. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tools/check_cli_patterns.py +0 -0
  401. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tools/generate_cli_commands_registry.py +0 -0
  402. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tools/generate_requirements_mapping.py +0 -0
  403. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tools/sync_mcp_registry.py +0 -0
  404. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tools/sync_mcp_version.py +0 -0
  405. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tools/sync_plugin_version.py +0 -0
  406. {affinity_sdk-0.9.2 → affinity_sdk-0.9.11}/tools/validate_openapi_models.py +0 -0
@@ -3,22 +3,20 @@ name: Release MCP Plugin
3
3
  on:
4
4
  push:
5
5
  tags: ["mcp-v*.*.*"] # Renamed from plugin-v*
6
- workflow_call:
6
+ workflow_dispatch:
7
7
  inputs:
8
8
  version:
9
- description: "Version to release (without prefix)"
10
- required: true
9
+ description: "Version to release (without prefix, for API trigger)"
10
+ required: false
11
11
  type: string
12
12
  triggered_by:
13
13
  description: "What triggered this release"
14
14
  required: false
15
15
  type: string
16
- default: "tag"
17
- workflow_dispatch:
18
- inputs:
16
+ default: "manual"
19
17
  tag:
20
- description: 'Tag to release (e.g., mcp-v1.0.0)'
21
- required: true
18
+ description: 'Tag to release manually (e.g., mcp-v1.0.0, ignored if version set)'
19
+ required: false
22
20
 
23
21
  permissions:
24
22
  contents: write
@@ -32,24 +30,37 @@ jobs:
32
30
  run: |
33
31
  set -euo pipefail
34
32
  if [[ -n "${{ inputs.version }}" ]]; then
35
- # Called via workflow_call
33
+ # API-triggered release (from release-detect)
34
+ # Note: Version validation happens post-checkout in "Validate version matches VERSION file" step
36
35
  echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT
37
36
  echo "tag_name=mcp-v${{ inputs.version }}" >> $GITHUB_OUTPUT
38
- echo "is_workflow_call=true" >> $GITHUB_OUTPUT
39
- echo "Mode: workflow_call, version=${{ inputs.version }}"
37
+ echo "is_api_trigger=true" >> $GITHUB_OUTPUT
38
+ echo "Mode: workflow_dispatch (API), version=${{ inputs.version }}, triggered_by=${{ inputs.triggered_by }}"
39
+ elif [[ "${GITHUB_EVENT_NAME}" == "push" && "${GITHUB_REF_TYPE}" == "tag" ]]; then
40
+ # Tag push
41
+ TAG_NAME="${GITHUB_REF_NAME}"
42
+ VERSION="${TAG_NAME#mcp-v}"
43
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
44
+ echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
45
+ echo "is_api_trigger=false" >> $GITHUB_OUTPUT
46
+ echo "Mode: tag push, tag=$TAG_NAME, version=$VERSION"
40
47
  else
41
- # Called via tag push or workflow_dispatch
42
- TAG_NAME="${{ github.event.inputs.tag || github.ref_name }}"
48
+ # Manual workflow_dispatch with tag input
49
+ TAG_NAME="${{ inputs.tag }}"
50
+ if [[ -z "$TAG_NAME" ]]; then
51
+ echo "::error::Manual dispatch requires either 'version' or 'tag' input"
52
+ exit 1
53
+ fi
43
54
  VERSION="${TAG_NAME#mcp-v}"
44
55
  echo "version=$VERSION" >> $GITHUB_OUTPUT
45
56
  echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
46
- echo "is_workflow_call=false" >> $GITHUB_OUTPUT
47
- echo "Mode: tag/dispatch, tag=$TAG_NAME, version=$VERSION"
57
+ echo "is_api_trigger=false" >> $GITHUB_OUTPUT
58
+ echo "Mode: workflow_dispatch (manual), tag=$TAG_NAME, version=$VERSION"
48
59
  fi
49
60
 
50
61
  - uses: actions/checkout@v6
51
62
  with:
52
- ref: ${{ steps.version.outputs.is_workflow_call == 'true' && 'main' || (github.event.inputs.tag || github.ref) }}
63
+ ref: ${{ steps.version.outputs.is_api_trigger == 'true' && 'main' || (github.event.inputs.tag || github.ref) }}
53
64
 
54
65
  - name: Validate version matches VERSION file
55
66
  run: |
@@ -118,8 +129,8 @@ jobs:
118
129
  "$EXTRACT_DIR/server/run-server.sh" --health || echo "Health check not available (expected if CLI not configured)"
119
130
  rm -rf "$EXTRACT_DIR"
120
131
 
121
- - name: Create and push tag
122
- if: steps.version.outputs.is_workflow_call == 'true'
132
+ - name: Create and push tag (API trigger only)
133
+ if: steps.version.outputs.is_api_trigger == 'true'
123
134
  run: |
124
135
  git config user.name "github-actions[bot]"
125
136
  git config user.email "github-actions[bot]@users.noreply.github.com"
@@ -15,6 +15,7 @@ on:
15
15
 
16
16
  permissions:
17
17
  contents: read
18
+ actions: write # Required for workflow_dispatch API
18
19
 
19
20
  jobs:
20
21
  detect-changes:
@@ -76,23 +77,59 @@ jobs:
76
77
  trigger-sdk-release:
77
78
  needs: detect-changes
78
79
  if: needs.detect-changes.outputs.sdk_changed == 'true'
79
- uses: ./.github/workflows/release.yml
80
- with:
81
- version: ${{ needs.detect-changes.outputs.sdk_version }}
82
- triggered_by: version-bump
83
- secrets: inherit
84
- permissions:
85
- contents: write
86
- id-token: write
87
- attestations: write
80
+ runs-on: ubuntu-latest
81
+ steps:
82
+ - name: Trigger SDK release workflow
83
+ uses: actions/github-script@v7
84
+ with:
85
+ script: |
86
+ // Use toJSON for safe string interpolation
87
+ const version = ${{ toJSON(needs.detect-changes.outputs.sdk_version) }};
88
+ console.log(`Triggering SDK release workflow for version ${version}`);
89
+
90
+ try {
91
+ await github.rest.actions.createWorkflowDispatch({
92
+ owner: context.repo.owner,
93
+ repo: context.repo.repo,
94
+ workflow_id: 'release.yml',
95
+ ref: 'main',
96
+ inputs: {
97
+ version: version,
98
+ triggered_by: 'release-detect'
99
+ }
100
+ });
101
+ console.log(`✅ SDK release workflow triggered successfully for v${version}`);
102
+ } catch (error) {
103
+ console.error(`❌ Failed to trigger SDK release: ${error.message}`);
104
+ core.setFailed(`Failed to trigger SDK release workflow: ${error.message}`);
105
+ }
88
106
 
89
107
  trigger-mcp-release:
90
108
  needs: detect-changes
91
109
  if: needs.detect-changes.outputs.mcp_changed == 'true'
92
- uses: ./.github/workflows/plugin-release.yml
93
- with:
94
- version: ${{ needs.detect-changes.outputs.mcp_version }}
95
- triggered_by: version-bump
96
- secrets: inherit
97
- permissions:
98
- contents: write
110
+ runs-on: ubuntu-latest
111
+ steps:
112
+ - name: Trigger MCP plugin release workflow
113
+ uses: actions/github-script@v7
114
+ with:
115
+ script: |
116
+ // Use toJSON for safe string interpolation
117
+ const version = ${{ toJSON(needs.detect-changes.outputs.mcp_version) }};
118
+ console.log(`Triggering MCP plugin release workflow for version ${version}`);
119
+
120
+ try {
121
+ await github.rest.actions.createWorkflowDispatch({
122
+ owner: context.repo.owner,
123
+ repo: context.repo.repo,
124
+ workflow_id: 'plugin-release.yml',
125
+ ref: 'main',
126
+ inputs: {
127
+ version: version,
128
+ triggered_by: 'release-detect'
129
+ }
130
+ });
131
+ console.log(`✅ MCP release workflow triggered successfully for v${version}`);
132
+ } catch (error) {
133
+ console.error(`❌ Failed to trigger MCP release: ${error.message}`);
134
+ core.setFailed(`Failed to trigger MCP release workflow: ${error.message}`);
135
+ }
@@ -3,22 +3,20 @@ name: Release (PyPI)
3
3
  on:
4
4
  push:
5
5
  tags: ["v*.*.*"]
6
- workflow_call:
6
+ workflow_dispatch:
7
7
  inputs:
8
8
  version:
9
- description: "Version to release (without v prefix)"
10
- required: true
9
+ description: "Version to release (without v prefix, for API trigger)"
10
+ required: false
11
11
  type: string
12
12
  triggered_by:
13
13
  description: "What triggered this release"
14
14
  required: false
15
15
  type: string
16
- default: "tag"
17
- workflow_dispatch:
18
- inputs:
16
+ default: "manual"
19
17
  target:
20
- description: "Publish target (manual runs only)"
21
- required: true
18
+ description: "Publish target (manual TestPyPI only, ignored if version set)"
19
+ required: false
22
20
  default: "none"
23
21
  type: choice
24
22
  options:
@@ -31,7 +29,8 @@ permissions:
31
29
  attestations: write
32
30
 
33
31
  concurrency:
34
- group: release-${{ github.ref }}
32
+ # Use version for API triggers, ref_name for tag pushes
33
+ group: release-${{ inputs.version || github.ref_name }}
35
34
  cancel-in-progress: false
36
35
 
37
36
  jobs:
@@ -41,7 +40,7 @@ jobs:
41
40
  tag_name: ${{ steps.meta.outputs.tag_name }}
42
41
  version_tag: ${{ steps.meta.outputs.version_tag }}
43
42
  publish_target: ${{ steps.meta.outputs.publish_target }}
44
- is_workflow_call: ${{ steps.meta.outputs.is_workflow_call }}
43
+ is_api_trigger: ${{ steps.meta.outputs.is_api_trigger }}
45
44
  steps:
46
45
  - uses: actions/checkout@v6
47
46
  with:
@@ -53,16 +52,22 @@ jobs:
53
52
  run: |
54
53
  set -euo pipefail
55
54
 
56
- # Check if this is a workflow_call (version input provided)
57
55
  if [[ -n "${{ inputs.version }}" ]]; then
58
- echo "is_workflow_call=true" >> "$GITHUB_OUTPUT"
56
+ # API-triggered release (from release-detect)
57
+ # IMPORTANT: Verify version matches pyproject.toml to prevent mismatches
58
+ PYPROJECT_VERSION=$(grep '^version = ' pyproject.toml | head -1 | cut -d'"' -f2)
59
+ if [[ "${{ inputs.version }}" != "$PYPROJECT_VERSION" ]]; then
60
+ echo "::error::Version mismatch: input=${{ inputs.version }}, pyproject.toml=$PYPROJECT_VERSION"
61
+ exit 1
62
+ fi
63
+ echo "is_api_trigger=true" >> "$GITHUB_OUTPUT"
59
64
  echo "version_tag=${{ inputs.version }}" >> "$GITHUB_OUTPUT"
60
65
  echo "tag_name=v${{ inputs.version }}" >> "$GITHUB_OUTPUT"
61
66
  echo "publish_target=pypi" >> "$GITHUB_OUTPUT"
62
- echo "Mode: workflow_call, version=${{ inputs.version }}"
67
+ echo "Mode: workflow_dispatch (API), version=${{ inputs.version }}, triggered_by=${{ inputs.triggered_by }}"
63
68
  elif [[ "${GITHUB_EVENT_NAME}" == "push" && "${GITHUB_REF_TYPE}" == "tag" ]]; then
64
69
  # Tag push
65
- echo "is_workflow_call=false" >> "$GITHUB_OUTPUT"
70
+ echo "is_api_trigger=false" >> "$GITHUB_OUTPUT"
66
71
  echo "publish_target=pypi" >> "$GITHUB_OUTPUT"
67
72
  echo "tag_name=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
68
73
  if [[ "${GITHUB_REF_NAME}" != v* ]]; then
@@ -72,16 +77,16 @@ jobs:
72
77
  echo "version_tag=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
73
78
  echo "Mode: tag push, tag=${GITHUB_REF_NAME}"
74
79
  else
75
- # Manual workflow_dispatch
76
- echo "is_workflow_call=false" >> "$GITHUB_OUTPUT"
80
+ # Manual workflow_dispatch (TestPyPI dry run)
81
+ echo "is_api_trigger=false" >> "$GITHUB_OUTPUT"
77
82
  echo "publish_target=${{ inputs.target }}" >> "$GITHUB_OUTPUT"
78
83
  echo "tag_name=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
79
84
  echo "version_tag=" >> "$GITHUB_OUTPUT"
80
- echo "Mode: workflow_dispatch, target=${{ inputs.target }}"
85
+ echo "Mode: workflow_dispatch (manual), target=${{ inputs.target }}"
81
86
  fi
82
87
 
83
88
  - name: Require tag ref for publishing (tag-triggered only)
84
- if: ${{ steps.meta.outputs.publish_target == 'pypi' && steps.meta.outputs.is_workflow_call != 'true' && github.ref_type != 'tag' }}
89
+ if: ${{ steps.meta.outputs.publish_target == 'pypi' && steps.meta.outputs.is_api_trigger != 'true' && github.ref_type != 'tag' }}
85
90
  shell: bash
86
91
  run: |
87
92
  echo "Publishing requires running the workflow on a tag ref (vX.Y.Z)." >&2
@@ -112,7 +117,7 @@ jobs:
112
117
  echo "Version validated: $PYPROJECT_VERSION"
113
118
 
114
119
  - name: Validate commit is on main (tag-triggered only)
115
- if: ${{ steps.meta.outputs.is_workflow_call != 'true' && github.ref_type == 'tag' }}
120
+ if: ${{ steps.meta.outputs.is_api_trigger != 'true' && github.ref_type == 'tag' }}
116
121
  shell: bash
117
122
  run: |
118
123
  set -euo pipefail
@@ -185,6 +190,47 @@ jobs:
185
190
  path: dist/
186
191
  if-no-files-found: error
187
192
 
193
+ # Build MCPB bundle for convenience (same commit as SDK)
194
+ - name: Install jq
195
+ run: sudo apt-get install -y jq
196
+
197
+ - name: Install mcp-bash framework
198
+ run: |
199
+ # Source version and commit from lockfile (single source of truth)
200
+ source mcp/mcp-bash.lock
201
+ echo "Installing mcp-bash v${MCPBASH_VERSION} (${MCPBASH_COMMIT})"
202
+ curl -fsSL https://raw.githubusercontent.com/yaniv-golan/mcp-bash-framework/main/install.sh | \
203
+ bash -s -- --version "v${MCPBASH_VERSION}" --yes
204
+ echo "$HOME/.local/bin" >> $GITHUB_PATH
205
+ # Verify installed commit matches lockfile
206
+ INSTALLED_COMMIT=$(git -C "${XDG_DATA_HOME:-$HOME/.local/share}/mcp-bash" rev-parse HEAD)
207
+ if [[ "$INSTALLED_COMMIT" != "$MCPBASH_COMMIT" ]]; then
208
+ echo "::error::mcp-bash commit mismatch: expected $MCPBASH_COMMIT, got $INSTALLED_COMMIT"
209
+ exit 1
210
+ fi
211
+
212
+ - name: Build Claude Code plugin ZIP
213
+ run: |
214
+ cd mcp
215
+ make plugin
216
+ echo "Plugin version: $(cat .claude-plugin/VERSION)"
217
+ ls -la .claude-plugin/xaffinity-mcp-plugin.zip
218
+
219
+ - name: Build MCPB bundle
220
+ run: |
221
+ cd mcp
222
+ mcp-bash bundle --output dist --verbose
223
+ ls -la dist/*.mcpb
224
+
225
+ - name: Upload MCPB artifacts
226
+ uses: actions/upload-artifact@v6
227
+ with:
228
+ name: mcpb-${{ needs.validate.outputs.tag_name }}
229
+ path: |
230
+ mcp/.claude-plugin/xaffinity-mcp-plugin.zip
231
+ mcp/dist/*.mcpb
232
+ if-no-files-found: error
233
+
188
234
  publish:
189
235
  runs-on: ubuntu-latest
190
236
  needs: [validate, build]
@@ -197,25 +243,22 @@ jobs:
197
243
  name: dist-${{ needs.validate.outputs.tag_name }}
198
244
  path: dist/
199
245
 
200
- # Note: attestations are disabled for workflow_call because PyPI's Trusted
201
- # Publishing attestation feature doesn't support reusable workflows.
202
- # See: https://docs.pypi.org/trusted-publishers/troubleshooting/#reusable-workflows-on-github
203
246
  - name: Publish to PyPI (trusted publishing)
204
247
  if: ${{ needs.validate.outputs.publish_target == 'pypi' }}
205
248
  uses: pypa/gh-action-pypi-publish@release/v1
206
249
  with:
207
- attestations: ${{ needs.validate.outputs.is_workflow_call != 'true' }}
250
+ attestations: true
208
251
 
209
252
  - name: Publish to TestPyPI (trusted publishing)
210
253
  if: ${{ needs.validate.outputs.publish_target == 'testpypi' }}
211
254
  uses: pypa/gh-action-pypi-publish@release/v1
212
255
  with:
213
256
  repository-url: https://test.pypi.org/legacy/
214
- attestations: ${{ needs.validate.outputs.is_workflow_call != 'true' }}
257
+ attestations: true
215
258
 
216
259
  github-release:
217
260
  runs-on: ubuntu-latest
218
- needs: [validate, publish]
261
+ needs: [validate, build, publish]
219
262
  if: ${{ needs.validate.outputs.publish_target == 'pypi' }}
220
263
  steps:
221
264
  - uses: actions/checkout@v6
@@ -239,8 +282,14 @@ jobs:
239
282
  name: dist-${{ needs.validate.outputs.tag_name }}
240
283
  path: dist/
241
284
 
242
- - name: Create and push tag (workflow_call only)
243
- if: ${{ needs.validate.outputs.is_workflow_call == 'true' }}
285
+ - name: Download MCPB artifacts
286
+ uses: actions/download-artifact@v7
287
+ with:
288
+ name: mcpb-${{ needs.validate.outputs.tag_name }}
289
+ path: mcpb/
290
+
291
+ - name: Create and push tag (API trigger only)
292
+ if: ${{ needs.validate.outputs.is_api_trigger == 'true' }}
244
293
  run: |
245
294
  git config user.name "github-actions[bot]"
246
295
  git config user.email "github-actions[bot]@users.noreply.github.com"
@@ -253,7 +302,9 @@ jobs:
253
302
  tag_name: ${{ needs.validate.outputs.tag_name }}
254
303
  name: SDK ${{ needs.validate.outputs.tag_name }}
255
304
  body_path: release_notes.md
256
- files: dist/*
305
+ files: |
306
+ dist/*
307
+ mcpb/**/*
257
308
  fail_on_unmatched_files: true
258
309
 
259
310
  smoke-test:
@@ -269,11 +320,15 @@ jobs:
269
320
  with:
270
321
  python-version: "3.12"
271
322
 
272
- - name: Smoke test installation
323
+ - name: Smoke test SDK installation
324
+ run: |
325
+ pip install affinity-sdk==${{ needs.validate.outputs.version_tag }}
326
+ python -c "from affinity import Affinity; print('SDK import OK')"
327
+
328
+ - name: Smoke test CLI installation
273
329
  run: |
274
- pip install affinity-api==${{ needs.validate.outputs.version_tag }}
275
- python -c "from affinity import Affinity; print('Import OK')"
276
- python -c "from affinity.cli import app; print('CLI OK')"
330
+ pip install "affinity-sdk[cli]==${{ needs.validate.outputs.version_tag }}"
331
+ python -c "from affinity.cli import cli; print('CLI import OK')"
277
332
 
278
333
  - name: Warn on failure
279
334
  if: failure()
@@ -58,3 +58,4 @@ tools/tmp_readonly_endpoint_syntax_suite.py
58
58
  tmp-scripts/set_primary_email_status.py
59
59
  test-output/
60
60
  CLAUDE.md
61
+ .sandbox.env
@@ -5,8 +5,151 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ ## 0.9.11 - 2026-01-17
11
+
12
+ ### Added
13
+ - CLI: Query `include` clause now displays included relationships inline by default. Use `--include-style=separate` for separate tables or `--include-style=ids-only` for raw IDs. JSON output includes full `included` and `included_by_parent` mappings for correlation.
14
+ - CLI: Query `include` extended syntax for custom display fields: `include: {companies: {display: ["name", "domain"]}}`.
15
+ - SDK: `with_interaction_dates` and `with_interaction_persons` parameters for `CompanyService.get()` and `PersonService.get()`. When enabled, routes to V1 API to fetch interaction date summaries (last/next meeting, email dates, team member IDs).
16
+ - CLI: `--expand interactions` option for `list export` command. Adds interaction date summaries to each list entry (last meeting, next meeting, last email, last interaction with daysSince/daysUntil calculations and team member names). Supports both JSON and CSV output formats.
17
+ - CLI: `expand: ["interactionDates"]` support in `query` command. Enriches records with interaction date summaries directly on each record in `result.data`. Works with `persons`, `companies`, and `listEntries` queries.
18
+ - CLI: `--check-unreplied-emails` flag for `list export` command. Detects unreplied incoming emails for each list entry and adds date, daysSince, and subject to output. Use `--unreplied-lookback-days` to configure lookback period (default: 30 days).
19
+ - CLI: `--with-interaction-dates` and `--with-interaction-persons` flags for `company get` and `person get` commands. Fetches interaction date summaries directly in entity get operations.
20
+ - MCP: Query tool `format` parameter now functional (was previously ignored). Supports `toon`, `markdown`, `json`, `jsonl`, `csv`.
21
+ - CLI: `--max-output-bytes` option for `query` command. Enables format-aware truncation for MCP use, returning exit code 100 when truncated.
22
+ - CLI: `format_toon_envelope()` function for TOON output with full envelope (`data[N]{...}:`, `pagination:`, `included_*:` sections).
23
+ - SDK: Batch association methods for PersonService, CompanyService, and OpportunityService:
24
+ - `get_associated_company_ids_batch(person_ids)` / `get_associated_opportunity_ids_batch(person_ids)`
25
+ - `get_associated_person_ids_batch(company_ids)` / `get_associated_opportunity_ids_batch(company_ids)`
26
+ - `get_associated_person_ids_batch(opportunity_ids)` / `get_associated_company_ids_batch(opportunity_ids)`
27
+ - All return `dict[EntityId, list[AssocId]]` with `on_error="raise"|"skip"` parameter.
28
+ - SDK: `retries` parameter on `persons.get()`, `companies.get()`, and `opportunities.get()` methods. Enables automatic retry with exponential backoff on 404 errors to handle V1→V2 eventual consistency after create operations. Default is `retries=0` (fail fast).
29
+ - CLI: Reminder date options now accept relative dates and keywords in addition to ISO-8601:
30
+ - `--due-date`: `+7d`, `+2w`, `+1m`, `+1y`, `today`, `tomorrow`, `yesterday`, `now`
31
+ - `--due-after`, `--due-before`: Same formats for filtering in `reminder ls`
32
+ - Example: `xaffinity reminder create --due-date +7d --type one-time --owner-id 123`
33
+ - CLI: Domain validation for `company create` and `company update` now provides helpful error messages:
34
+ - Detects underscores (RFC 1035 violation) and suggests dash replacement
35
+ - Detects URL prefixes and extracts domain
36
+ - Example: `--domain test_company.com` → "Use 'test-company.com' instead"
37
+ - Docs: V1→V2 eventual consistency guide covering 404 after create and stale data after update scenarios.
38
+ - Tests: Integration test suite for SDK write operations (`tests/integration/`).
39
+
40
+ ### Changed
41
+ - SDK: `OpportunityService.get_associated_people()` and `get_associated_companies()` now use V2 batch lookup instead of individual V1 fetches, reducing N+1 API calls (e.g., 50 people now fetched in 2 calls instead of 51).
42
+ - SDK: Query executor `_batch_fetch_by_ids()` now uses V2 batch lookup for persons and companies, improving query performance on relationship includes.
43
+ - CLI: Query `include` clause now fetches relationship IDs in parallel, then batch-fetches full records via V2 API, reducing API calls from N×M to N+1 for deduped lookups.
44
+
45
+ ### Changed (Breaking)
46
+ - MCP: Query tool default format changed from `json` to `toon` for better token efficiency (~40% fewer tokens).
47
+ - CLI: TOON query output now includes full envelope structure instead of data-only format. The `data` prefix is added to the array header: `data[N]{fields}:` instead of `[N]{fields}:`.
48
+
49
+ ### Fixed
50
+ - MCP: Query tool now honors the `format` parameter instead of always using JSON output.
51
+ - SDK: `ListEntryService.batch_update_fields()` now uses correct V2 API payload format. Previously failed with "Missing discriminator for property operation" error.
52
+
53
+ ## 0.9.9 - 2026-01-14
54
+
55
+ ### Added
56
+ - CLI: `query` command now supports advanced relationship filtering:
57
+ - `all` quantifier: Filter where all related items match a condition (e.g., find persons where all their companies have ".com" domains)
58
+ - `none` quantifier: Filter where no related items match a condition (e.g., find persons with no spam interactions)
59
+ - `exists` subquery: Filter where at least one related item exists, optionally matching a condition (e.g., find persons who have email interactions)
60
+ - `_count` pseudo-field: Filter by count of related items (e.g., `"path": "companies._count", "op": "gte", "value": 2`)
61
+ - Available relationship paths: persons→companies/opportunities/interactions/notes/listEntries, companies→persons/opportunities/interactions/notes/listEntries, opportunities→persons/companies/interactions
62
+ - Note: These features cause N+1 API calls to fetch relationship data; use `--dry-run` to preview
63
+
64
+ ### Changed (Breaking)
65
+ - CLI: Renamed relationship `"people"` to `"persons"` for consistency with entity type names:
66
+ - Query `include`: `{"from": "companies", "include": ["people"]}` → use `["persons"]`
67
+ - CLI `--expand`: `xaffinity company get <id> --expand people` → use `--expand persons`
68
+ - JSON output: `data.people` → `data.persons`
69
+
70
+ ### Fixed
71
+ - CLI: Query engine no longer silently passes all records for `all`, `none`, and `_count` filters. Previously these were placeholder implementations that returned `True` for all records, causing incorrect query results. (Bug #15)
72
+
73
+ ## 0.9.8 - 2026-01-12
74
+
75
+ ### Fixed
76
+ - CLI: `query` command now correctly fetches all records before applying filter, sort, or aggregate operations. Previously, limits were applied during fetch which caused incorrect results:
77
+ - With filters: Empty results when matching records were beyond the limit position
78
+ - With sort + limit: Random N records sorted instead of actual top N
79
+ - With aggregate: Inaccurate counts/sums computed on partial data
80
+
81
+ ## 0.9.7 - 2026-01-12
82
+
83
+ ### Fixed
84
+ - CI: Smoke test now correctly installs CLI extras before testing CLI import
85
+
86
+ ## 0.9.6 - 2026-01-12
87
+
88
+ ### Added
89
+ - CLI: `listEntries` queries now include convenience aliases: `listEntryId`, `entityId`, `entityName`, `entityType`. These intuitive field names work in both `select` and `where` clauses.
90
+ - CLI: `listEntries` records now always include a `fields` key (defaults to `{}` if no custom fields).
91
+
92
+ ### Changed
93
+ - CLI: Query projection now includes null values for explicitly selected fields. Previously, `select: ["entityName", "fields.Status"]` would return `{}` if Status was null; now returns `{"entityName": "Acme", "fields": {"Status": null}}`.
94
+
95
+ ## 0.9.5 - 2026-01-12
96
+
97
+ ### Added
98
+ - CLI: New `--output`/`-o` option supporting multiple formats: `json`, `jsonl`, `markdown`, `toon`, `csv`, `table` (default).
99
+ - `markdown`: GitHub-flavored markdown tables, best for LLM analysis and comprehension
100
+ - `toon`: Token-Optimized Object Notation, 30-60% fewer tokens than JSON for large datasets
101
+ - `jsonl`: JSON Lines format, one object per line for streaming workflows
102
+ - Example: `xaffinity person ls --output markdown`, `xaffinity query -o toon`
103
+ - Existing `--csv` and `--json` flags continue to work as before.
104
+
105
+ ### Changed
106
+ - CLI: `to_cell()` now extracts "text" from dropdown/multi-select fields instead of JSON-serializing the full dict. This makes CSV and other tabular outputs human-readable for dropdown values.
107
+
108
+ ### Fixed
109
+ - CLI: `query` command with `limit` now correctly returns results when combined with client-side filters (like `has_any` on multi-select fields). Previously, the limit was applied during fetch before filtering, causing empty results when the first N records didn't match the filter criteria.
110
+
111
+ ## 0.9.4 - 2026-01-12
112
+
113
+ ### Added
114
+ - CLI: `query` command now supports `has_any` and `has_all` operators for multi-select field filtering.
115
+ - SDK/CLI: Filter parser now supports V2 API comparison operators: `>`, `>=`, `<`, `<=` for numeric/date comparisons.
116
+ - SDK/CLI: Filter parser now supports word-based operator aliases for LLM/human clarity:
117
+ - `contains`, `starts_with`, `ends_with` (string matching)
118
+ - `gt`, `gte`, `lt`, `lte` (numeric/date comparisons)
119
+ - `is null`, `is not null`, `is empty` (null/empty checks)
120
+ - SDK/CLI: Filter parser now supports collection bracket syntax `[A, B, C]` with operators:
121
+ - `in [A, B]` - value is one of the listed values
122
+ - `between [1, 10]` - value is in range (inclusive)
123
+ - `has_any [A, B]` - array field contains any of the values
124
+ - `has_all [A, B]` - array field contains all of the values
125
+ - `contains_any [A, B]` - substring match for any term
126
+ - `contains_all [A, B]` - substring match for all terms
127
+ - `= [A, B]` - set equality (array has exactly these elements)
128
+ - `=~ [A, B]` - V2 API collection contains (array contains all elements)
129
+
130
+ ### Fixed
131
+ - CLI: `query` command now correctly filters on multi-select dropdown fields (like "Team Member"). The `eq` operator checks array membership for scalar values and set equality for array values. Previously, these queries returned 0 results due to strict equality comparison.
132
+ - SDK/CLI: `list export --filter` now correctly matches multi-select dropdown fields. The `=`, `!=`, and `=~` operators now handle array values properly. Also fixes extraction of text values from multi-select dropdown API responses.
133
+ - SDK/CLI: Fixed `=^` (starts_with) and `=$` (ends_with) operators which were broken due to tokenizer ordering issue.
134
+
135
+ ### Improved
136
+ - SDK/CLI: Filter parser now provides helpful hints for common mistakes:
137
+ - Multi-word field names: suggests quoting (`"Team Member"`)
138
+ - Multi-word values: suggests quoting (`"Intro Meeting"`)
139
+ - SQL keywords (`AND`, `OR`): suggests correct symbols (`&`, `|`)
140
+ - Double equals (`==`): suggests single `=`
141
+
142
+ ## 0.9.3 - 2026-01-11
143
+
144
+ ### Changed
145
+ - CI: SDK releases now include MCPB bundle and plugin ZIP for convenience.
146
+ - CI: Enabled PyPI attestations via workflow_dispatch API trigger.
147
+
8
148
  ## 0.9.2 - 2026-01-11
9
149
 
150
+ ### Fixed
151
+ - SDK: `AsyncListEntryService.pages()` now supports `progress_callback` parameter (sync/async parity fix).
152
+
10
153
  ### Changed
11
154
  - **BREAKING**: CLI: `interaction ls` JSON output restructured for consistency:
12
155
  - `.data.interactions` → `.data` (direct array)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: affinity-sdk
3
- Version: 0.9.2
3
+ Version: 0.9.11
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/
@@ -69,7 +69,12 @@ The release detection workflow compares the current version in version files aga
69
69
  3. It checks if release tags exist:
70
70
  - SDK: checks for `v{version}` tag (e.g., `v0.9.2`)
71
71
  - MCP: checks for `mcp-v{version}` tag (e.g., `mcp-v1.7.6`)
72
- 4. If no tag exists for the current version, it triggers the release workflow
72
+ 4. If no tag exists for the current version, it triggers the release workflow via `workflow_dispatch` API
73
+
74
+ The release workflows are triggered via GitHub's workflow_dispatch API (not reusable workflows). This enables:
75
+ - **PyPI attestations**: Full provenance attestation support for all releases
76
+ - **GITHUB_TOKEN**: No PATs or GitHub Apps required
77
+ - **Tag creation post-publish**: Tags are created after successful PyPI publish (SDK) or GitHub release (MCP)
73
78
 
74
79
  This approach is robust regardless of how many commits are pushed together, squash merges, rebases, or any other git workflow.
75
80
 
@@ -82,6 +87,8 @@ This approach is robust regardless of how many commits are pushed together, squa
82
87
  5. Commit and push to `main` (or merge PR)
83
88
  6. **Release runs automatically** — tag created post-release
84
89
 
90
+ SDK releases include MCPB bundles (built from the same commit) for convenience, so users don't need to find separate MCP releases.
91
+
85
92
  ### MCP Release
86
93
 
87
94
  1. Update `mcp/VERSION`
@@ -5,3 +5,7 @@ This package is only intended to be used when installing `affinity-sdk[cli]`.
5
5
  """
6
6
 
7
7
  from __future__ import annotations
8
+
9
+ from .main import cli
10
+
11
+ __all__ = ["cli"]
@@ -0,0 +1,6 @@
1
+ """Enable running the CLI via `python -m affinity.cli`."""
2
+
3
+ from affinity.cli.main import cli
4
+
5
+ if __name__ == "__main__":
6
+ cli()
@@ -94,9 +94,9 @@ async def dump_entity_files_bundle(
94
94
  break
95
95
  if max_files is not None and produced >= max_files:
96
96
  break
97
- if not resp.next_page_token:
97
+ if not resp.next_cursor:
98
98
  break
99
- token = resp.next_page_token
99
+ token = resp.next_cursor
100
100
 
101
101
  for _ in range(workers):
102
102
  await queue.put(None)