affinity-sdk 0.9.9__tar.gz → 0.9.14__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 (412) hide show
  1. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/workflows/ci.yml +10 -5
  2. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/workflows/release.yml +2 -2
  3. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.gitignore +2 -0
  4. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.pre-commit-config.yaml +7 -0
  5. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/CHANGELOG.md +88 -1
  6. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/PKG-INFO +3 -1
  7. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/README.md +2 -0
  8. affinity_sdk-0.9.14/affinity/cli/__main__.py +6 -0
  9. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/_entity_files_dump.py +2 -2
  10. affinity_sdk-0.9.14/affinity/cli/commands/_v1_parsing.py +186 -0
  11. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/company_cmds.py +32 -8
  12. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/interaction_cmds.py +1 -1
  13. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/list_cmds.py +253 -17
  14. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/note_cmds.py +10 -5
  15. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/opportunity_cmds.py +6 -12
  16. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/person_cmds.py +50 -10
  17. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/query_cmd.py +59 -16
  18. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/reminder_cmds.py +75 -17
  19. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/task_cmds.py +22 -3
  20. affinity_sdk-0.9.14/affinity/cli/constants.py +16 -0
  21. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/context.py +1 -0
  22. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/formatters.py +108 -0
  23. affinity_sdk-0.9.14/affinity/cli/interaction_utils.py +580 -0
  24. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/query/aggregates.py +12 -4
  25. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/query/executor.py +1030 -69
  26. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/query/filters.py +108 -0
  27. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/query/models.py +114 -2
  28. affinity_sdk-0.9.14/affinity/cli/query/output.py +1104 -0
  29. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/query/parser.py +46 -6
  30. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/query/planner.py +190 -18
  31. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/query/schema.py +105 -3
  32. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/resolve.py +55 -1
  33. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/clients/http.py +2 -2
  34. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/models/entities.py +14 -4
  35. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/models/pagination.py +55 -14
  36. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/models/types.py +19 -8
  37. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/services/companies.py +384 -50
  38. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/services/lists.py +155 -35
  39. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/services/opportunities.py +153 -60
  40. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/services/persons.py +456 -44
  41. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/services/v1_only.py +275 -19
  42. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/cli/commands.md +44 -0
  43. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/cli/index.md +10 -0
  44. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/cli/scripting.md +85 -1
  45. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/api-versions-and-routing.md +4 -0
  46. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/errors-and-retries.md +55 -1
  47. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/pagination.md +37 -2
  48. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/performance.md +43 -0
  49. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/query-command.md +106 -1
  50. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/query-language.md +169 -5
  51. affinity_sdk-0.9.14/docs/public/reference/services/companies.md +47 -0
  52. affinity_sdk-0.9.14/docs/public/reference/services/persons.md +42 -0
  53. affinity_sdk-0.9.14/docs/public/troubleshooting.md +58 -0
  54. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/.claude-plugin/plugin.json +1 -1
  55. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/.claude-plugin/skills/affinity-mcp-workflows/SKILL.md +48 -23
  56. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/.claude-plugin/skills/query-language/SKILL.md +177 -13
  57. affinity_sdk-0.9.9/mcp/.registry/commands.json → affinity_sdk-0.9.14/mcp/.registry/commands.generated.json +509 -310
  58. affinity_sdk-0.9.14/mcp/.registry/mcp-commands.json +362 -0
  59. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/.registry/prompts.json +1 -1
  60. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/.registry/resource-templates.json +1 -1
  61. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/.registry/resources.json +2 -2
  62. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/CHANGELOG.md +79 -9
  63. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/COMPATIBILITY +8 -2
  64. affinity_sdk-0.9.14/mcp/VERSION +1 -0
  65. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/lib/cli-gateway.sh +38 -25
  66. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/lib/common.sh +3 -2
  67. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/mcp-bash.lock +2 -2
  68. affinity_sdk-0.9.14/mcp/mcpb.conf +49 -0
  69. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/resources/data-model/data-model.md +54 -0
  70. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/server.d/env.sh +28 -1
  71. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/server.d/health-checks.sh +3 -3
  72. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/server.d/server.meta.json +1 -1
  73. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/test/run.sh +46 -0
  74. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/tools/discover-commands/tool.sh +25 -3
  75. affinity_sdk-0.9.14/mcp/tools/execute-read-command/tool.meta.json +36 -0
  76. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/tools/execute-read-command/tool.sh +14 -12
  77. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/tools/execute-write-command/tool.meta.json +1 -1
  78. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/tools/execute-write-command/tool.sh +23 -25
  79. affinity_sdk-0.9.14/mcp/tools/query/tool.meta.json +104 -0
  80. affinity_sdk-0.9.14/mcp/tools/query/tool.sh +183 -0
  81. affinity_sdk-0.9.14/mcp/user-config.json +35 -0
  82. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mkdocs.yml +2 -0
  83. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/plugins/affinity-sdk/.claude-plugin/plugin.json +1 -1
  84. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/plugins/xaffinity-cli/.claude-plugin/plugin.json +1 -1
  85. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/pyproject.toml +3 -2
  86. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/cli/test_formatters.py +191 -0
  87. affinity_sdk-0.9.14/tests/cli/test_query_list_entry_relationships.py +643 -0
  88. affinity_sdk-0.9.14/tests/cli/test_query_list_export_parity.py +319 -0
  89. affinity_sdk-0.9.14/tests/cli/test_query_output_flattening.py +668 -0
  90. affinity_sdk-0.9.14/tests/cli/test_query_output_truncation.py +685 -0
  91. affinity_sdk-0.9.14/tests/cli/test_query_unreplied_emails.py +251 -0
  92. affinity_sdk-0.9.14/tests/integration/README.md +186 -0
  93. affinity_sdk-0.9.14/tests/integration/conftest.py +122 -0
  94. affinity_sdk-0.9.14/tests/integration/setup_query_parity_data.py +414 -0
  95. affinity_sdk-0.9.14/tests/integration/test_cli_writes.py +594 -0
  96. affinity_sdk-0.9.14/tests/integration/test_query_parity_integration.py +1124 -0
  97. affinity_sdk-0.9.14/tests/integration/test_sdk_reads.py +470 -0
  98. affinity_sdk-0.9.14/tests/integration/test_sdk_writes.py +1767 -0
  99. affinity_sdk-0.9.14/tests/integration/test_sdk_writes_runner.py +225 -0
  100. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_company_get.py +21 -18
  101. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_csv_export.py +33 -14
  102. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_entity_files_dump.py +1 -0
  103. affinity_sdk-0.9.14/tests/test_cli_get_interaction_dates.py +262 -0
  104. affinity_sdk-0.9.14/tests/test_cli_interaction_utils.py +588 -0
  105. affinity_sdk-0.9.14/tests/test_cli_list_expand_interactions.py +332 -0
  106. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_opportunity_cmds.py +50 -39
  107. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_query_aggregates.py +26 -0
  108. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_query_executor.py +506 -1
  109. affinity_sdk-0.9.14/tests/test_cli_query_expand_interactions.py +1042 -0
  110. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_query_filters.py +262 -0
  111. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_query_integration.py +153 -0
  112. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_query_planner.py +408 -0
  113. affinity_sdk-0.9.14/tests/test_cli_unreplied_email.py +244 -0
  114. affinity_sdk-0.9.14/tests/test_cli_v1_parsing.py +195 -0
  115. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_field_value_type.py +3 -2
  116. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_models.py +5 -2
  117. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_requirements_additional.py +2 -2
  118. affinity_sdk-0.9.14/tests/test_sdk_interaction_dates.py +600 -0
  119. affinity_sdk-0.9.14/tests/test_service_get_parameter_combinations.py +339 -0
  120. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_services_lists_additional_coverage.py +10 -3
  121. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_services_opportunities_additional_coverage.py +82 -16
  122. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_services_persons_companies_additional_coverage.py +476 -52
  123. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_small_modules_coverage.py +54 -4
  124. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_v1_only_services_more_coverage.py +1 -1
  125. affinity_sdk-0.9.14/tools/generate_mcp_command_registry.py +239 -0
  126. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tools/sync_mcp_registry.py +2 -2
  127. affinity_sdk-0.9.9/affinity/cli/commands/_v1_parsing.py +0 -77
  128. affinity_sdk-0.9.9/affinity/cli/query/output.py +0 -339
  129. affinity_sdk-0.9.9/docs/public/reference/services/companies.md +0 -10
  130. affinity_sdk-0.9.9/docs/public/reference/services/persons.md +0 -5
  131. affinity_sdk-0.9.9/docs/public/troubleshooting.md +0 -22
  132. affinity_sdk-0.9.9/mcp/.registry/commands-metadata.json +0 -109
  133. affinity_sdk-0.9.9/mcp/VERSION +0 -1
  134. affinity_sdk-0.9.9/mcp/mcpb.conf +0 -24
  135. affinity_sdk-0.9.9/mcp/tools/execute-read-command/tool.meta.json +0 -42
  136. affinity_sdk-0.9.9/mcp/tools/query/tool.meta.json +0 -100
  137. affinity_sdk-0.9.9/mcp/tools/query/tool.sh +0 -106
  138. affinity_sdk-0.9.9/tools/generate_cli_commands_registry.py +0 -200
  139. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.claude-plugin/marketplace.json +0 -0
  140. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.editorconfig +0 -0
  141. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.env.example +0 -0
  142. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.gitattributes +0 -0
  143. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/CODEOWNERS +0 -0
  144. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  145. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  146. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/PULL_REQUEST_TEMPLATE/cli_command.md +0 -0
  147. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/PULL_REQUEST_TEMPLATE/release.md +0 -0
  148. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/dependabot.yml +0 -0
  149. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/labels.yml +0 -0
  150. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/pull_request_template.md +0 -0
  151. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/workflows/docs.yml +0 -0
  152. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/workflows/labels.yml +0 -0
  153. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/workflows/linkcheck.yml +0 -0
  154. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/workflows/openapi-validation.yml +0 -0
  155. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/workflows/plugin-build.yml +0 -0
  156. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/workflows/plugin-release.yml +0 -0
  157. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/workflows/release-detect.yml +0 -0
  158. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/.github/workflows/version-check.yml +0 -0
  159. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/CODE_OF_CONDUCT.md +0 -0
  160. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/CONTRIBUTING.md +0 -0
  161. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/LICENSE +0 -0
  162. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/SECURITY.md +0 -0
  163. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/VERSIONING.md +0 -0
  164. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/__init__.py +0 -0
  165. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/__init__.py +0 -0
  166. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/click_compat.py +0 -0
  167. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/__init__.py +0 -0
  168. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/_list_entry_fields.py +0 -0
  169. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/completion_cmd.py +0 -0
  170. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/config_cmds.py +0 -0
  171. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/entry_cmds.py +0 -0
  172. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/field_cmds.py +0 -0
  173. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/relationship_strength_cmds.py +0 -0
  174. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/resolve_url_cmd.py +0 -0
  175. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/session_cmds.py +0 -0
  176. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/version_cmd.py +0 -0
  177. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/commands/whoami_cmd.py +0 -0
  178. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/config.py +0 -0
  179. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/csv_utils.py +0 -0
  180. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/date_utils.py +0 -0
  181. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/decorators.py +0 -0
  182. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/errors.py +0 -0
  183. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/field_utils.py +0 -0
  184. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/help_json.py +0 -0
  185. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/logging.py +0 -0
  186. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/main.py +0 -0
  187. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/options.py +0 -0
  188. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/paths.py +0 -0
  189. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/progress.py +0 -0
  190. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/query/__init__.py +0 -0
  191. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/query/dates.py +0 -0
  192. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/query/exceptions.py +0 -0
  193. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/query/progress.py +0 -0
  194. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/render.py +0 -0
  195. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/resolvers.py +0 -0
  196. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/results.py +0 -0
  197. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/runner.py +0 -0
  198. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/serialization.py +0 -0
  199. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/session_cache.py +0 -0
  200. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/cli/types.py +0 -0
  201. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/client.py +0 -0
  202. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/clients/__init__.py +0 -0
  203. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/clients/pipeline.py +0 -0
  204. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/compare.py +0 -0
  205. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/downloads.py +0 -0
  206. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/exceptions.py +0 -0
  207. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/filters.py +0 -0
  208. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/hooks.py +0 -0
  209. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/inbound_webhooks.py +0 -0
  210. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/models/__init__.py +0 -0
  211. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/models/rate_limit_snapshot.py +0 -0
  212. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/models/secondary.py +0 -0
  213. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/policies.py +0 -0
  214. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/progress.py +0 -0
  215. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/py.typed +0 -0
  216. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/services/__init__.py +0 -0
  217. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/services/rate_limits.py +0 -0
  218. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/services/tasks.py +0 -0
  219. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/affinity/types.py +0 -0
  220. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/codecov.yml +0 -0
  221. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/cli-development-guide.md +0 -0
  222. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/ai-integrations/index.md +0 -0
  223. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/changelog.md +0 -0
  224. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/cli-reference.md +0 -0
  225. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/examples.md +0 -0
  226. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/getting-started.md +0 -0
  227. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/glossary.md +0 -0
  228. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/authentication.md +0 -0
  229. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/claude-code-plugins.md +0 -0
  230. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/configuration.md +0 -0
  231. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/csv-export.md +0 -0
  232. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/datetime-handling.md +0 -0
  233. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/debugging-hooks.md +0 -0
  234. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/field-types-and-values.md +0 -0
  235. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/field-values.md +0 -0
  236. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/filtering.md +0 -0
  237. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/ids-and-types.md +0 -0
  238. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/models.md +0 -0
  239. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/opportunity-associations.md +0 -0
  240. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/rate-limits.md +0 -0
  241. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/sync-vs-async.md +0 -0
  242. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/guides/webhooks.md +0 -0
  243. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/index.md +0 -0
  244. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/mcp/index.md +0 -0
  245. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/client.md +0 -0
  246. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/exceptions.md +0 -0
  247. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/filters.md +0 -0
  248. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/models.md +0 -0
  249. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/services/lists.md +0 -0
  250. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/services/opportunities.md +0 -0
  251. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/services/tasks.md +0 -0
  252. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/services/v1/auth.md +0 -0
  253. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/services/v1/field-values.md +0 -0
  254. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/services/v1/fields.md +0 -0
  255. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/services/v1/files.md +0 -0
  256. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/services/v1/interactions.md +0 -0
  257. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/services/v1/notes.md +0 -0
  258. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/services/v1/relationships.md +0 -0
  259. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/services/v1/reminders.md +0 -0
  260. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/services/v1/webhooks.md +0 -0
  261. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/docs/public/reference/types.md +0 -0
  262. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/examples/advanced_usage.py +0 -0
  263. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/examples/async_lifecycle.py +0 -0
  264. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/examples/basic_usage.py +0 -0
  265. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/examples/filter_builder.py +0 -0
  266. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/examples/hooks_debugging.py +0 -0
  267. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/examples/list_management.py +0 -0
  268. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/examples/resolve_helpers.py +0 -0
  269. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/examples/task_polling.py +0 -0
  270. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/.claude-plugin/.gitignore +0 -0
  271. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/.claude-plugin/.mcp.json +0 -0
  272. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/.claude-plugin/xaffinity-mcp.sh +0 -0
  273. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/.gitignore +0 -0
  274. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/Makefile +0 -0
  275. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/README.md +0 -0
  276. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/completions/entity-name.sh +0 -0
  277. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/completions/list-name.sh +0 -0
  278. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/completions/status-value.sh +0 -0
  279. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/docs/DEBUGGING.md +0 -0
  280. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/docs/internal/debugging-improvements-plan.md +0 -0
  281. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/docs/internal/mcp-bash-progress-timeout-feature-request.md +0 -0
  282. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/icon.svg +0 -0
  283. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/lib/cache.sh +0 -0
  284. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/lib/entity-types.sh +0 -0
  285. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/lib/field-resolution.sh +0 -0
  286. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/change-status/change-status.meta.json +0 -0
  287. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/change-status/change-status.txt +0 -0
  288. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/interaction-brief/interaction-brief.meta.json +0 -0
  289. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/interaction-brief/interaction-brief.txt +0 -0
  290. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/log-call/log-call.meta.json +0 -0
  291. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/log-call/log-call.txt +0 -0
  292. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/log-interaction-and-update-workflow/log-interaction-and-update-workflow.meta.json +0 -0
  293. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/log-interaction-and-update-workflow/log-interaction-and-update-workflow.txt +0 -0
  294. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/log-message/log-message.meta.json +0 -0
  295. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/log-message/log-message.txt +0 -0
  296. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/pipeline-review/pipeline-review.meta.json +0 -0
  297. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/pipeline-review/pipeline-review.txt +0 -0
  298. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/prepare-briefing/prepare-briefing.meta.json +0 -0
  299. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/prepare-briefing/prepare-briefing.txt +0 -0
  300. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/warm-intro/warm-intro.meta.json +0 -0
  301. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/prompts/warm-intro/warm-intro.txt +0 -0
  302. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/providers/xaffinity.sh +0 -0
  303. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/resources/data-model/data-model.meta.json +0 -0
  304. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/resources/field-catalogs/field-catalogs.meta.json +0 -0
  305. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/resources/field-catalogs/field-catalogs.sh +0 -0
  306. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/resources/interaction-enums/interaction-enums.json +0 -0
  307. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/resources/interaction-enums/interaction-enums.meta.json +0 -0
  308. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/resources/me/me.meta.json +0 -0
  309. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/resources/me/me.sh +0 -0
  310. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/resources/me-person-id/me-person-id.meta.json +0 -0
  311. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/resources/me-person-id/me-person-id.sh +0 -0
  312. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/resources/saved-views/saved-views.meta.json +0 -0
  313. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/resources/saved-views/saved-views.sh +0 -0
  314. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/resources/workflow-config/workflow-config.meta.json +0 -0
  315. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/resources/workflow-config/workflow-config.sh +0 -0
  316. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/scripts/install-framework.sh +0 -0
  317. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/server.d/policy.sh +0 -0
  318. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/server.d/requirements.json +0 -0
  319. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/test/README.md +0 -0
  320. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/test-progress.sh +0 -0
  321. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/tools/discover-commands/tool.meta.json +0 -0
  322. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/tools/get-entity-dossier/tool.meta.json +0 -0
  323. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/tools/get-entity-dossier/tool.sh +0 -0
  324. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/tools/read-xaffinity-resource/tool.meta.json +0 -0
  325. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/tools/read-xaffinity-resource/tool.sh +0 -0
  326. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/xaffinity-mcp-env.sh +0 -0
  327. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/mcp/xaffinity-mcp.sh +0 -0
  328. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/plugins/affinity-sdk/.claude-plugin/skills/affinity-python-sdk/SKILL.md +0 -0
  329. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/plugins/xaffinity-cli/.claude-plugin/commands/affinity-help.md +0 -0
  330. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/plugins/xaffinity-cli/.claude-plugin/hooks/hooks.json +0 -0
  331. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/plugins/xaffinity-cli/.claude-plugin/hooks/pre-xaffinity.sh +0 -0
  332. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/plugins/xaffinity-cli/.claude-plugin/skills/xaffinity-cli-usage/SKILL.md +0 -0
  333. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/cli/test_output_formats_integration.py +0 -0
  334. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/conftest.py +0 -0
  335. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/fixtures/webhooks/field_value_updated.json +0 -0
  336. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/fixtures/webhooks/list_entry_created.json +0 -0
  337. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/fixtures/webhooks/organization_created.json +0 -0
  338. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/fixtures/webhooks/organization_merged.json +0 -0
  339. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/fixtures/webhooks/person_created.json +0 -0
  340. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/fixtures/webhooks/unknown_event.json +0 -0
  341. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_affinity_client_wrapper_additional_coverage.py +0 -0
  342. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_async_file_download_streaming.py +0 -0
  343. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_column_limiting.py +0 -0
  344. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_command_context.py +0 -0
  345. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_company_cmds_coverage.py +0 -0
  346. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_config_cmds.py +0 -0
  347. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_date_params.py +0 -0
  348. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_date_utils.py +0 -0
  349. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_datetime_formatting.py +0 -0
  350. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_datetime_header_offsets.py +0 -0
  351. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_domain_linkification.py +0 -0
  352. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_entry_field.py +0 -0
  353. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_error_rendering.py +0 -0
  354. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_field_history.py +0 -0
  355. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_field_value_humanization.py +0 -0
  356. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_interaction_date_chunking.py +0 -0
  357. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_json_safety.py +0 -0
  358. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_list_cmds_coverage.py +0 -0
  359. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_missing_coverage.py +0 -0
  360. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_no_network_commands.py +0 -0
  361. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_opportunity_cmds_coverage.py +0 -0
  362. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_pager_logic.py +0 -0
  363. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_person_cmds_coverage.py +0 -0
  364. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_person_get.py +0 -0
  365. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_progress_manager.py +0 -0
  366. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_query_cmd.py +0 -0
  367. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_query_dates.py +0 -0
  368. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_query_parser.py +0 -0
  369. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_query_safety.py +0 -0
  370. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_query_schema.py +0 -0
  371. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_rate_limit_rendering.py +0 -0
  372. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_resolve_url_parsing.py +0 -0
  373. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_result_summary.py +0 -0
  374. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_serialization.py +0 -0
  375. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_session_cache.py +0 -0
  376. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_types.py +0 -0
  377. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_v1_only_cmds.py +0 -0
  378. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_cli_write_ops.py +0 -0
  379. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_client.py +0 -0
  380. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_compare.py +0 -0
  381. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_env_helpers.py +0 -0
  382. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_exceptions_coverage.py +0 -0
  383. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_file_download_streaming.py +0 -0
  384. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_file_upload_helpers_and_validation.py +0 -0
  385. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_filters.py +0 -0
  386. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_hooks.py +0 -0
  387. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_http_client_additional_coverage.py +0 -0
  388. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_http_client_remaining_coverage.py +0 -0
  389. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_inbound_webhooks.py +0 -0
  390. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_integration_smoke.py +0 -0
  391. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_interactions_and_files_regressions.py +0 -0
  392. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_isodatetime.py +0 -0
  393. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_list_entry_membership_and_opportunities.py +0 -0
  394. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_new_features.py +0 -0
  395. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_pagination_iterators.py +0 -0
  396. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_public_api.py +0 -0
  397. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_raw_pipeline_hook_events.py +0 -0
  398. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_services_companies_coverage_gaps.py +0 -0
  399. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_services_lists_coverage_gaps.py +0 -0
  400. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_services_opportunities_coverage_gaps.py +0 -0
  401. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_services_opportunities_tasks_additional_coverage.py +0 -0
  402. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_services_rate_limits_coverage_gaps.py +0 -0
  403. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_services_v1_only_async.py +0 -0
  404. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_services_v1_only_coverage_gaps.py +0 -0
  405. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_transport_and_readonly_mode.py +0 -0
  406. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tests/test_v1_only_services_additional_coverage.py +0 -0
  407. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tools/check_cli_patterns.py +0 -0
  408. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tools/generate_requirements_mapping.py +0 -0
  409. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tools/sync_mcp_version.py +0 -0
  410. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tools/sync_plugin_version.py +0 -0
  411. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/tools/validate_openapi_models.py +0 -0
  412. {affinity_sdk-0.9.9 → affinity_sdk-0.9.14}/uv.lock +0 -0
@@ -84,14 +84,19 @@ jobs:
84
84
  echo "Skipping traceability mapping (docs/internal not present in repo checkout)."
85
85
  fi
86
86
 
87
- - name: CLI commands registry is valid
87
+ - name: MCP commands registry is valid
88
88
  run: |
89
89
  # Verify registry file exists and is valid JSON with expected structure
90
90
  python -c "
91
91
  import json
92
92
  import sys
93
- with open('mcp/.registry/commands.json') as f:
93
+ with open('mcp/.registry/commands.generated.json') as f:
94
94
  data = json.load(f)
95
+ # Check _generated metadata (auto-generated indicator)
96
+ assert '_generated' in data, 'Missing _generated metadata'
97
+ assert 'generator' in data['_generated'], 'Missing generator in _generated'
98
+ assert 'cliVersion' in data['_generated'], 'Missing cliVersion in _generated'
99
+ # Check commands structure
95
100
  assert 'commands' in data, 'Missing commands key'
96
101
  assert isinstance(data['commands'], list), 'commands must be a list'
97
102
  assert len(data['commands']) > 0, 'commands list is empty'
@@ -99,11 +104,11 @@ jobs:
99
104
  assert 'name' in cmd, f'Command missing name: {cmd}'
100
105
  assert 'category' in cmd, f'Command {cmd[\"name\"]} missing category'
101
106
  assert cmd['category'] in ('read', 'write', 'local'), f'Invalid category for {cmd[\"name\"]}'
102
- print(f'Registry valid: {len(data[\"commands\"])} commands')
107
+ print(f'Registry valid: {len(data[\"commands\"])} commands (v{data[\"_generated\"][\"cliVersion\"]})')
103
108
  "
104
109
  # Regenerate registry and verify it matches committed version
105
- python tools/generate_cli_commands_registry.py
106
- git diff --exit-code mcp/.registry/commands.json
110
+ python tools/generate_mcp_command_registry.py
111
+ git diff --exit-code mcp/.registry/commands.generated.json
107
112
 
108
113
  test-timezone:
109
114
  runs-on: ubuntu-latest
@@ -159,8 +159,8 @@ jobs:
159
159
 
160
160
  - name: Verify registry is up to date
161
161
  run: |
162
- python tools/generate_cli_commands_registry.py
163
- git diff --exit-code mcp/.registry/commands.json
162
+ python tools/generate_mcp_command_registry.py
163
+ git diff --exit-code mcp/.registry/commands.generated.json
164
164
 
165
165
  build:
166
166
  runs-on: ubuntu-latest
@@ -58,3 +58,5 @@ 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
62
+ tests/integration/query_parity_test_data.json
@@ -66,3 +66,10 @@ repos:
66
66
  language: python
67
67
  files: ^(mcp/VERSION|mcp/\.claude-plugin/plugin\.json|mcp/server\.d/server\.meta\.json)$
68
68
  pass_filenames: false
69
+ - id: pytest-pre-push
70
+ name: Run tests before push
71
+ entry: pytest tests/ -x -q --tb=short
72
+ language: system
73
+ pass_filenames: false
74
+ stages: [pre-push]
75
+ always_run: true
@@ -5,6 +5,85 @@ 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.14 - 2026-01-19
11
+
12
+ ### Fixed
13
+ - CLI: Query `select` clause now automatically includes `expand` fields. Previously, using `select` with `expand` would filter out the expansion data (e.g., `interactionDates`, `unrepliedEmails`), requiring users to explicitly list expansions in `select`.
14
+
15
+ ## 0.9.13 - 2026-01-19
16
+
17
+ ### Added
18
+ - CLI: Query `include` for `listEntries` now supports `persons`, `companies`, `opportunities`, and `interactions`. Fetches related entities based on list entry entity type (e.g., company entries get associated persons).
19
+ - CLI: Query `expand: ["unrepliedEmails"]` now works with `listEntries`. Checks each list entry's underlying entity for unreplied incoming emails.
20
+ - CLI: Query extended include syntax with parameters:
21
+ - `{include: {interactions: {limit: 50, days: 180}}}` - Limit and lookback control
22
+ - `{include: {opportunities: {list: "Pipeline"}}}` - Scope to specific opportunity list
23
+ - `{include: {persons: {where: {...}}}}` - Filter included entities
24
+
25
+ ### Fixed
26
+ - CLI: Query TOON format now correctly flattens `fields.*` and `interactionDates` like markdown and CSV formats do. Previously, TOON was missing the `_apply_explicit_flattening()` call, causing nested fields to be truncated and interaction dates to be missing entirely.
27
+ - CLI: `list export --check-unreplied-emails` now works standalone without requiring `--expand`.
28
+ - CLI: `expand: ["interactionDates"]` now always produces 8 canonical columns regardless of data presence, ensuring consistent schema across all records.
29
+ - SDK: Improved error message when adding wrong entity type to a list (e.g., adding a company to a person list). Now provides clear guidance about list type requirements instead of exposing raw API validation error.
30
+
31
+ ### Performance
32
+ - CLI: Query `expand: ["interactionDates"]` is significantly faster with parallel person resolution, bounded concurrent fetches (semaphore=10), and parallelized section resolution. Default concurrency increased from 5 to 15 (tunable via `XAFFINITY_QUERY_CONCURRENCY`).
33
+
34
+ ## 0.9.12 - 2026-01-17
35
+
36
+ ### Changed
37
+ - CLI: Query `listEntries` now normalizes reference field values to display strings:
38
+ - Person fields: `{"firstName": "Jane", "lastName": "Doe"}` → `"Jane Doe"`
39
+ - Company fields: `{"name": "Acme Corp", "id": 123}` → `"Acme Corp"`
40
+ - Multi-person/company fields: Arrays of names instead of raw objects
41
+ - Use `expand` or `include` for full entity data when needed
42
+ - CLI: Query output with explicit `select` on `fields.*` paths now flattens fields to top-level columns in table/CSV/markdown formats. JSON output preserves nested structure.
43
+
44
+ ## 0.9.11 - 2026-01-17
45
+
46
+ ### Added
47
+ - 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.
48
+ - CLI: Query `include` extended syntax for custom display fields: `include: {companies: {display: ["name", "domain"]}}`.
49
+ - 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).
50
+ - 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.
51
+ - 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.
52
+ - 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).
53
+ - 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.
54
+ - MCP: Query tool `format` parameter now functional (was previously ignored). Supports `toon`, `markdown`, `json`, `jsonl`, `csv`.
55
+ - CLI: `--max-output-bytes` option for `query` command. Enables format-aware truncation for MCP use, returning exit code 100 when truncated.
56
+ - CLI: `format_toon_envelope()` function for TOON output with full envelope (`data[N]{...}:`, `pagination:`, `included_*:` sections).
57
+ - SDK: Batch association methods for PersonService, CompanyService, and OpportunityService:
58
+ - `get_associated_company_ids_batch(person_ids)` / `get_associated_opportunity_ids_batch(person_ids)`
59
+ - `get_associated_person_ids_batch(company_ids)` / `get_associated_opportunity_ids_batch(company_ids)`
60
+ - `get_associated_person_ids_batch(opportunity_ids)` / `get_associated_company_ids_batch(opportunity_ids)`
61
+ - All return `dict[EntityId, list[AssocId]]` with `on_error="raise"|"skip"` parameter.
62
+ - 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).
63
+ - CLI: Reminder date options now accept relative dates and keywords in addition to ISO-8601:
64
+ - `--due-date`: `+7d`, `+2w`, `+1m`, `+1y`, `today`, `tomorrow`, `yesterday`, `now`
65
+ - `--due-after`, `--due-before`: Same formats for filtering in `reminder ls`
66
+ - Example: `xaffinity reminder create --due-date +7d --type one-time --owner-id 123`
67
+ - CLI: Domain validation for `company create` and `company update` now provides helpful error messages:
68
+ - Detects underscores (RFC 1035 violation) and suggests dash replacement
69
+ - Detects URL prefixes and extracts domain
70
+ - Example: `--domain test_company.com` → "Use 'test-company.com' instead"
71
+ - Docs: V1→V2 eventual consistency guide covering 404 after create and stale data after update scenarios.
72
+ - Tests: Integration test suite for SDK write operations (`tests/integration/`).
73
+
74
+ ### Changed
75
+ - 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).
76
+ - SDK: Query executor `_batch_fetch_by_ids()` now uses V2 batch lookup for persons and companies, improving query performance on relationship includes.
77
+ - 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.
78
+
79
+ ### Changed (Breaking)
80
+ - MCP: Query tool default format changed from `json` to `toon` for better token efficiency (~40% fewer tokens).
81
+ - 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}:`.
82
+
83
+ ### Fixed
84
+ - MCP: Query tool now honors the `format` parameter instead of always using JSON output.
85
+ - SDK: `ListEntryService.batch_update_fields()` now uses correct V2 API payload format. Previously failed with "Missing discriminator for property operation" error.
86
+
8
87
  ## 0.9.9 - 2026-01-14
9
88
 
10
89
  ### Added
@@ -162,7 +241,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
162
241
  - CLI: `--limit` alias for `--max-results` on all `ls` commands (LLM-friendly).
163
242
  - CLI: Option aliases now included in `--help --json` output.
164
243
 
165
- ## 0.8.0 - Unreleased
244
+ ## 0.8.2 - 2026-01-10
245
+
246
+ _No user-facing changes. Version bump for PyPI release._
247
+
248
+ ## 0.8.1 - 2026-01-10
249
+
250
+ _No user-facing changes. Version bump for PyPI release._
251
+
252
+ ## 0.8.0 - 2026-01-10
166
253
 
167
254
  ### Changed
168
255
  - CLI: Renamed `--json` to `--set-json` on `person field`, `company field`, `opportunity field` commands to avoid conflict with global `--json` output flag.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: affinity-sdk
3
- Version: 0.9.9
3
+ Version: 0.9.14
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/
@@ -126,6 +126,8 @@ Optional: install the CLI:
126
126
  pipx install "affinity-sdk[cli]"
127
127
  ```
128
128
 
129
+ The CLI includes a powerful `query` command for structured data extraction with filtering, aggregations, and relationship includes. Output formats include JSON, CSV, markdown, and TOON (token-optimized for LLMs).
130
+
129
131
  CLI docs: https://yaniv-golan.github.io/affinity-sdk/latest/cli/
130
132
 
131
133
  ### MCP Server
@@ -69,6 +69,8 @@ Optional: install the CLI:
69
69
  pipx install "affinity-sdk[cli]"
70
70
  ```
71
71
 
72
+ The CLI includes a powerful `query` command for structured data extraction with filtering, aggregations, and relationship includes. Output formats include JSON, CSV, markdown, and TOON (token-optimized for LLMs).
73
+
72
74
  CLI docs: https://yaniv-golan.github.io/affinity-sdk/latest/cli/
73
75
 
74
76
  ### MCP Server
@@ -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)
@@ -0,0 +1,186 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from collections.abc import Mapping
5
+ from datetime import datetime, timezone
6
+ from typing import Any, TypeVar
7
+
8
+ from ..errors import CLIError
9
+ from ..query.dates import is_relative_date, parse_relative_date
10
+
11
+ T = TypeVar("T")
12
+
13
+
14
+ def parse_choice(value: str | None, mapping: Mapping[str, T], *, label: str) -> T | None:
15
+ if value is None:
16
+ return None
17
+ key = value.strip().lower()
18
+ if key in mapping:
19
+ return mapping[key]
20
+ choices = ", ".join(sorted(mapping.keys()))
21
+ raise CLIError(
22
+ f"Unknown {label}: {value}",
23
+ error_type="usage_error",
24
+ exit_code=2,
25
+ hint=f"Choose one of: {choices}.",
26
+ )
27
+
28
+
29
+ def validate_domain(value: str | None, *, label: str = "domain") -> str | None:
30
+ """
31
+ Validate domain format before API call.
32
+
33
+ Checks for common domain format mistakes that would be rejected by the
34
+ Affinity API with a cryptic error message. Validates against RFC 1035
35
+ constraints and common user errors.
36
+
37
+ Args:
38
+ value: Domain string to validate (or None)
39
+ label: Human-readable label for error messages
40
+
41
+ Returns:
42
+ The validated domain string (unchanged), or None if input was None
43
+
44
+ Raises:
45
+ CLIError: If domain format is invalid
46
+ """
47
+ if value is None:
48
+ return None
49
+
50
+ domain = value.strip()
51
+ if not domain:
52
+ return None
53
+
54
+ # Check for protocol prefix (common mistake)
55
+ if domain.startswith(("http://", "https://")):
56
+ # Extract domain from URL
57
+ clean = domain.split("//", 1)[1].split("/", 1)[0]
58
+ raise CLIError(
59
+ f"Invalid {label}: provide domain only, not URL",
60
+ error_type="usage_error",
61
+ exit_code=2,
62
+ hint=f"Use '{clean}' instead of '{value}'.",
63
+ )
64
+
65
+ # Check for underscores (RFC 1035 violation - most common issue)
66
+ if "_" in domain:
67
+ suggested = domain.replace("_", "-")
68
+ raise CLIError(
69
+ f"Invalid {label}: domains cannot contain underscores",
70
+ error_type="usage_error",
71
+ exit_code=2,
72
+ hint=f"Use '{suggested}' instead of '{domain}'.",
73
+ )
74
+
75
+ # Check for spaces
76
+ if " " in domain:
77
+ raise CLIError(
78
+ f"Invalid {label}: domains cannot contain spaces",
79
+ error_type="usage_error",
80
+ exit_code=2,
81
+ hint="Remove spaces from the domain.",
82
+ )
83
+
84
+ return domain
85
+
86
+
87
+ def parse_iso_datetime(value: str, *, label: str) -> datetime:
88
+ """
89
+ Parse ISO-8601 datetime string to UTC-aware datetime.
90
+
91
+ Timezone handling:
92
+ - Explicit timezone (Z or offset): Respected, converted to UTC
93
+ - Naive string: Interpreted as LOCAL time, converted to UTC
94
+
95
+ This provides intuitive UX for CLI users who think in local time.
96
+
97
+ Examples (assuming user is in EST/UTC-5):
98
+ "2024-01-01" → 2024-01-01T05:00:00Z (midnight EST)
99
+ "2024-01-01T12:00:00" → 2024-01-01T17:00:00Z (noon EST)
100
+ "2024-01-01T12:00:00Z" → 2024-01-01T12:00:00Z (explicit UTC)
101
+ "2024-01-01T12:00:00-05:00" → 2024-01-01T17:00:00Z (explicit EST)
102
+
103
+ Returns:
104
+ UTC-aware datetime object
105
+ """
106
+ raw = value.strip()
107
+ if raw.endswith("Z"):
108
+ raw = raw[:-1] + "+00:00"
109
+ try:
110
+ dt = datetime.fromisoformat(raw)
111
+ except ValueError as exc:
112
+ raise CLIError(
113
+ f"Invalid {label} datetime: {value}",
114
+ error_type="usage_error",
115
+ exit_code=2,
116
+ hint="Use ISO-8601, e.g. 2024-01-01, 2024-01-01T13:00:00, or 2024-01-01T13:00:00Z.",
117
+ ) from exc
118
+
119
+ # Convert to UTC
120
+ if dt.tzinfo is None:
121
+ # Naive datetime = local time
122
+ # astimezone() on naive datetime uses system timezone
123
+ dt = dt.astimezone()
124
+ return dt.astimezone(timezone.utc)
125
+
126
+
127
+ def parse_date_flexible(
128
+ value: str,
129
+ *,
130
+ label: str,
131
+ now: datetime | None = None,
132
+ ) -> datetime:
133
+ """
134
+ Parse date string as either relative or ISO format.
135
+
136
+ Tries relative first (+7d, tomorrow), then ISO-8601.
137
+ Returns UTC-aware datetime.
138
+
139
+ Args:
140
+ value: Date string to parse
141
+ label: Human-readable label for error messages
142
+ now: Reference time for relative dates (default: current UTC)
143
+
144
+ Returns:
145
+ UTC-aware datetime
146
+
147
+ Raises:
148
+ CLIError: If value cannot be parsed as either format
149
+ """
150
+ # Validate non-empty
151
+ if not value or not value.strip():
152
+ raise CLIError(
153
+ f"Missing {label} date value",
154
+ error_type="usage_error",
155
+ exit_code=2,
156
+ )
157
+
158
+ # Try relative date first
159
+ if is_relative_date(value):
160
+ try:
161
+ return parse_relative_date(value, now=now, use_utc=True)
162
+ except ValueError:
163
+ pass # Shouldn't happen if is_relative_date() returned True
164
+
165
+ # Fall back to ISO parsing, but wrap error with unified hint
166
+ try:
167
+ return parse_iso_datetime(value, label=label)
168
+ except CLIError:
169
+ raise CLIError(
170
+ f"Invalid {label} date: {value}",
171
+ error_type="usage_error",
172
+ exit_code=2,
173
+ hint="Use ISO-8601 (2026-01-01), relative (+7d, +2w), or keyword (today, tomorrow).",
174
+ ) from None
175
+
176
+
177
+ def parse_json_value(value: str, *, label: str) -> Any:
178
+ try:
179
+ return json.loads(value)
180
+ except json.JSONDecodeError as exc:
181
+ raise CLIError(
182
+ f"Invalid JSON for {label}.",
183
+ error_type="usage_error",
184
+ exit_code=2,
185
+ hint='Provide a valid JSON literal (e.g. "\\"text\\"", 123, true, {"k": 1}).',
186
+ ) from exc
@@ -32,6 +32,7 @@ from ._list_entry_fields import (
32
32
  build_list_entry_field_rows,
33
33
  filter_list_entry_fields,
34
34
  )
35
+ from ._v1_parsing import validate_domain
35
36
  from .resolve_url_cmd import _parse_affinity_url
36
37
 
37
38
 
@@ -484,7 +485,7 @@ def company_ls(
484
485
  page_size=page_size,
485
486
  page_token=cursor,
486
487
  ):
487
- next_cursor = v1_page.next_page_token
488
+ next_cursor = v1_page.next_cursor
488
489
  prev_cursor = None # V1 doesn't have prev cursor
489
490
 
490
491
  if v1_page.data:
@@ -526,7 +527,7 @@ def company_ls(
526
527
  page_size=page_size,
527
528
  page_token=cursor,
528
529
  ):
529
- next_cursor = search_page.next_page_token
530
+ next_cursor = search_page.next_cursor
530
531
  prev_cursor = None # Search doesn't have prev cursor
531
532
 
532
533
  for idx, company in enumerate(search_page.data):
@@ -717,7 +718,7 @@ def _resolve_company_by_domain(*, client: Any, domain: str) -> CompanyId:
717
718
  matches.append(company)
718
719
  if len(matches) >= 20:
719
720
  break
720
- if len(matches) >= 20 or not page.next_page_token:
721
+ if len(matches) >= 20 or not page.next_cursor:
721
722
  break
722
723
 
723
724
  if not matches:
@@ -758,7 +759,7 @@ def _resolve_company_by_name(*, client: Any, name: str) -> CompanyId:
758
759
  matches.append(company)
759
760
  if len(matches) >= 20:
760
761
  break
761
- if len(matches) >= 20 or not page.next_page_token:
762
+ if len(matches) >= 20 or not page.next_cursor:
762
763
  break
763
764
 
764
765
  if not matches:
@@ -915,7 +916,7 @@ def company_files_dump(
915
916
  ctx_modifiers["outDir"] = out_dir
916
917
  if overwrite:
917
918
  ctx_modifiers["overwrite"] = True
918
- if concurrency != 4:
919
+ if concurrency != 3:
919
920
  ctx_modifiers["concurrency"] = concurrency
920
921
  if page_size != 100:
921
922
  ctx_modifiers["pageSize"] = page_size
@@ -1119,6 +1120,18 @@ def company_files_upload(
1119
1120
  is_flag=True,
1120
1121
  help="Fetch all pages for expansions (still capped by --max-results if set).",
1121
1122
  )
1123
+ @click.option(
1124
+ "--with-interaction-dates",
1125
+ "with_interaction_dates",
1126
+ is_flag=True,
1127
+ help="Include interaction date summaries (last/next meeting, email dates).",
1128
+ )
1129
+ @click.option(
1130
+ "--with-interaction-persons",
1131
+ "with_interaction_persons",
1132
+ is_flag=True,
1133
+ help="Include person IDs for each interaction (requires --with-interaction-dates).",
1134
+ )
1122
1135
  @output_options
1123
1136
  @click.pass_obj
1124
1137
  def company_get(
@@ -1136,6 +1149,8 @@ def company_get(
1136
1149
  list_entry_fields_scope: ListEntryFieldsScope,
1137
1150
  max_results: int | None,
1138
1151
  all_pages: bool,
1152
+ with_interaction_dates: bool,
1153
+ with_interaction_persons: bool,
1139
1154
  ) -> None:
1140
1155
  """
1141
1156
  Get a company by id, URL, domain, or name.
@@ -1359,6 +1374,8 @@ def company_get(
1359
1374
  company_id,
1360
1375
  field_ids=field_ids,
1361
1376
  field_types=field_types_param,
1377
+ with_interaction_dates=with_interaction_dates,
1378
+ with_interaction_persons=with_interaction_persons,
1362
1379
  )
1363
1380
  company_payload = serialize_model_for_cli(company)
1364
1381
  fields_raw = getattr(company, "fields_raw", None)
@@ -1744,11 +1761,13 @@ def company_create(
1744
1761
  """Create a company."""
1745
1762
 
1746
1763
  def fn(ctx: CLIContext, warnings: list[str]) -> CommandOutput:
1764
+ validated_domain = validate_domain(domain, label="domain")
1765
+
1747
1766
  client = ctx.get_client(warnings=warnings)
1748
1767
  created = client.companies.create(
1749
1768
  CompanyCreate(
1750
1769
  name=name,
1751
- domain=domain,
1770
+ domain=validated_domain,
1752
1771
  person_ids=[PersonId(pid) for pid in person_ids],
1753
1772
  )
1754
1773
  )
@@ -1807,12 +1826,14 @@ def company_update(
1807
1826
  error_type="usage_error",
1808
1827
  hint="Use --name, --domain, or --person-id.",
1809
1828
  )
1829
+ validated_domain = validate_domain(domain, label="domain")
1830
+
1810
1831
  client = ctx.get_client(warnings=warnings)
1811
1832
  updated = client.companies.update(
1812
1833
  CompanyId(company_id),
1813
1834
  CompanyUpdate(
1814
1835
  name=name,
1815
- domain=domain,
1836
+ domain=validated_domain,
1816
1837
  person_ids=[PersonId(pid) for pid in person_ids] if person_ids else None,
1817
1838
  ),
1818
1839
  )
@@ -1883,7 +1904,10 @@ def company_merge(
1883
1904
  primary_id: int,
1884
1905
  duplicate_id: int,
1885
1906
  ) -> None:
1886
- """Merge a duplicate company into a primary company (beta)."""
1907
+ """Merge a duplicate company into a primary (beta).
1908
+
1909
+ Returns a taskUrl for tracking progress. Use 'task wait <url>' to wait for completion.
1910
+ """
1887
1911
 
1888
1912
  def fn(ctx: CLIContext, warnings: list[str]) -> CommandOutput:
1889
1913
  client = ctx.get_client(warnings=warnings)
@@ -288,7 +288,7 @@ def _fetch_interactions_chunked(
288
288
  chunks_processed=chunks_processed,
289
289
  )
290
290
 
291
- page_token = page.next_page_token
291
+ page_token = page.next_cursor
292
292
  if not page_token:
293
293
  break
294
294