affinity-sdk 0.9.2__tar.gz → 0.9.9__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 (380) hide show
  1. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/workflows/plugin-release.yml +29 -18
  2. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/workflows/release-detect.yml +53 -16
  3. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/workflows/release.yml +87 -32
  4. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/CHANGELOG.md +98 -0
  5. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/PKG-INFO +1 -1
  6. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/VERSIONING.md +8 -1
  7. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/__init__.py +4 -0
  8. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/company_cmds.py +14 -14
  9. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/list_cmds.py +77 -77
  10. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/opportunity_cmds.py +23 -23
  11. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/query_cmd.py +56 -4
  12. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/context.py +1 -1
  13. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/csv_utils.py +7 -17
  14. affinity_sdk-0.9.9/affinity/cli/formatters.py +551 -0
  15. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/options.py +9 -2
  16. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/query/executor.py +819 -64
  17. affinity_sdk-0.9.9/affinity/cli/query/filters.py +700 -0
  18. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/query/models.py +3 -1
  19. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/query/output.py +76 -8
  20. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/query/parser.py +2 -0
  21. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/query/planner.py +116 -8
  22. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/query/schema.py +35 -2
  23. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/runner.py +80 -25
  24. affinity_sdk-0.9.9/affinity/compare.py +501 -0
  25. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/filters.py +425 -37
  26. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/services/lists.py +133 -22
  27. affinity_sdk-0.9.9/codecov.yml +25 -0
  28. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/cli-development-guide.md +2 -2
  29. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/cli-reference.md +25 -2
  30. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/filtering.md +96 -33
  31. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/query-command.md +48 -2
  32. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/query-language.md +189 -21
  33. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/.claude-plugin/plugin.json +1 -1
  34. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/.claude-plugin/skills/affinity-mcp-workflows/SKILL.md +13 -4
  35. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/.claude-plugin/skills/query-language/SKILL.md +266 -18
  36. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/.registry/commands-metadata.json +11 -1
  37. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/.registry/commands.json +20 -12
  38. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/.registry/prompts.json +1 -1
  39. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/.registry/resource-templates.json +3 -3
  40. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/.registry/resources.json +2 -2
  41. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/CHANGELOG.md +82 -0
  42. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/COMPATIBILITY +15 -1
  43. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/README.md +125 -16
  44. affinity_sdk-0.9.9/mcp/VERSION +1 -0
  45. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/docs/DEBUGGING.md +8 -7
  46. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/lib/common.sh +50 -9
  47. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/mcp-bash.lock +2 -2
  48. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/resources/data-model/data-model.md +28 -6
  49. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/resources/field-catalogs/field-catalogs.meta.json +1 -1
  50. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/resources/field-catalogs/field-catalogs.sh +26 -11
  51. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/scripts/install-framework.sh +1 -1
  52. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/server.d/requirements.json +1 -1
  53. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/server.d/server.meta.json +1 -1
  54. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/test/README.md +3 -3
  55. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/tools/execute-read-command/tool.meta.json +6 -0
  56. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/tools/execute-read-command/tool.sh +27 -7
  57. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/tools/execute-write-command/tool.sh +27 -7
  58. affinity_sdk-0.9.9/mcp/tools/query/tool.meta.json +100 -0
  59. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/tools/query/tool.sh +17 -26
  60. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/plugins/affinity-sdk/.claude-plugin/plugin.json +1 -1
  61. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/plugins/xaffinity-cli/.claude-plugin/plugin.json +1 -1
  62. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/pyproject.toml +1 -1
  63. affinity_sdk-0.9.9/tests/cli/test_formatters.py +566 -0
  64. affinity_sdk-0.9.9/tests/cli/test_output_formats_integration.py +376 -0
  65. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_company_get.py +4 -4
  66. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_csv_export.py +12 -12
  67. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_opportunity_cmds.py +12 -12
  68. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_query_cmd.py +56 -27
  69. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_query_executor.py +1161 -30
  70. affinity_sdk-0.9.9/tests/test_cli_query_filters.py +1354 -0
  71. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_query_parser.py +1 -1
  72. affinity_sdk-0.9.9/tests/test_cli_query_safety.py +258 -0
  73. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_query_schema.py +2 -2
  74. affinity_sdk-0.9.9/tests/test_compare.py +518 -0
  75. affinity_sdk-0.9.9/tests/test_filters.py +1071 -0
  76. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/uv.lock +1 -1
  77. affinity_sdk-0.9.2/affinity/cli/query/filters.py +0 -330
  78. affinity_sdk-0.9.2/mcp/VERSION +0 -1
  79. affinity_sdk-0.9.2/mcp/tools/query/tool.meta.json +0 -94
  80. affinity_sdk-0.9.2/tests/test_cli_query_filters.py +0 -538
  81. affinity_sdk-0.9.2/tests/test_filters.py +0 -390
  82. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.claude-plugin/marketplace.json +0 -0
  83. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.editorconfig +0 -0
  84. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.env.example +0 -0
  85. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.gitattributes +0 -0
  86. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/CODEOWNERS +0 -0
  87. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  88. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  89. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/PULL_REQUEST_TEMPLATE/cli_command.md +0 -0
  90. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/PULL_REQUEST_TEMPLATE/release.md +0 -0
  91. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/dependabot.yml +0 -0
  92. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/labels.yml +0 -0
  93. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/pull_request_template.md +0 -0
  94. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/workflows/ci.yml +0 -0
  95. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/workflows/docs.yml +0 -0
  96. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/workflows/labels.yml +0 -0
  97. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/workflows/linkcheck.yml +0 -0
  98. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/workflows/openapi-validation.yml +0 -0
  99. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/workflows/plugin-build.yml +0 -0
  100. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.github/workflows/version-check.yml +0 -0
  101. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.gitignore +0 -0
  102. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/.pre-commit-config.yaml +0 -0
  103. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/CODE_OF_CONDUCT.md +0 -0
  104. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/CONTRIBUTING.md +0 -0
  105. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/LICENSE +0 -0
  106. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/README.md +0 -0
  107. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/SECURITY.md +0 -0
  108. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/__init__.py +0 -0
  109. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/click_compat.py +0 -0
  110. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/__init__.py +0 -0
  111. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/_entity_files_dump.py +0 -0
  112. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/_list_entry_fields.py +0 -0
  113. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/_v1_parsing.py +0 -0
  114. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/completion_cmd.py +0 -0
  115. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/config_cmds.py +0 -0
  116. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/entry_cmds.py +0 -0
  117. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/field_cmds.py +0 -0
  118. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/interaction_cmds.py +0 -0
  119. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/note_cmds.py +0 -0
  120. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/person_cmds.py +0 -0
  121. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/relationship_strength_cmds.py +0 -0
  122. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/reminder_cmds.py +0 -0
  123. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/resolve_url_cmd.py +0 -0
  124. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/session_cmds.py +0 -0
  125. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/task_cmds.py +0 -0
  126. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/version_cmd.py +0 -0
  127. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/commands/whoami_cmd.py +0 -0
  128. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/config.py +0 -0
  129. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/date_utils.py +0 -0
  130. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/decorators.py +0 -0
  131. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/errors.py +0 -0
  132. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/field_utils.py +0 -0
  133. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/help_json.py +0 -0
  134. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/logging.py +0 -0
  135. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/main.py +0 -0
  136. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/paths.py +0 -0
  137. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/progress.py +0 -0
  138. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/query/__init__.py +0 -0
  139. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/query/aggregates.py +0 -0
  140. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/query/dates.py +0 -0
  141. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/query/exceptions.py +0 -0
  142. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/query/progress.py +0 -0
  143. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/render.py +0 -0
  144. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/resolve.py +0 -0
  145. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/resolvers.py +0 -0
  146. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/results.py +0 -0
  147. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/serialization.py +0 -0
  148. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/session_cache.py +0 -0
  149. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/cli/types.py +0 -0
  150. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/client.py +0 -0
  151. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/clients/__init__.py +0 -0
  152. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/clients/http.py +0 -0
  153. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/clients/pipeline.py +0 -0
  154. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/downloads.py +0 -0
  155. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/exceptions.py +0 -0
  156. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/hooks.py +0 -0
  157. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/inbound_webhooks.py +0 -0
  158. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/models/__init__.py +0 -0
  159. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/models/entities.py +0 -0
  160. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/models/pagination.py +0 -0
  161. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/models/rate_limit_snapshot.py +0 -0
  162. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/models/secondary.py +0 -0
  163. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/models/types.py +0 -0
  164. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/policies.py +0 -0
  165. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/progress.py +0 -0
  166. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/py.typed +0 -0
  167. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/services/__init__.py +0 -0
  168. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/services/companies.py +0 -0
  169. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/services/opportunities.py +0 -0
  170. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/services/persons.py +0 -0
  171. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/services/rate_limits.py +0 -0
  172. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/services/tasks.py +0 -0
  173. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/services/v1_only.py +0 -0
  174. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/affinity/types.py +0 -0
  175. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/ai-integrations/index.md +0 -0
  176. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/changelog.md +0 -0
  177. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/cli/commands.md +0 -0
  178. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/cli/index.md +0 -0
  179. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/cli/scripting.md +0 -0
  180. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/examples.md +0 -0
  181. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/getting-started.md +0 -0
  182. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/glossary.md +0 -0
  183. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/api-versions-and-routing.md +0 -0
  184. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/authentication.md +0 -0
  185. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/claude-code-plugins.md +0 -0
  186. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/configuration.md +0 -0
  187. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/csv-export.md +0 -0
  188. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/datetime-handling.md +0 -0
  189. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/debugging-hooks.md +0 -0
  190. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/errors-and-retries.md +0 -0
  191. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/field-types-and-values.md +0 -0
  192. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/field-values.md +0 -0
  193. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/ids-and-types.md +0 -0
  194. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/models.md +0 -0
  195. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/opportunity-associations.md +0 -0
  196. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/pagination.md +0 -0
  197. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/performance.md +0 -0
  198. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/rate-limits.md +0 -0
  199. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/sync-vs-async.md +0 -0
  200. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/guides/webhooks.md +0 -0
  201. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/index.md +0 -0
  202. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/mcp/index.md +0 -0
  203. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/client.md +0 -0
  204. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/exceptions.md +0 -0
  205. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/filters.md +0 -0
  206. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/models.md +0 -0
  207. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/services/companies.md +0 -0
  208. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/services/lists.md +0 -0
  209. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/services/opportunities.md +0 -0
  210. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/services/persons.md +0 -0
  211. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/services/tasks.md +0 -0
  212. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/auth.md +0 -0
  213. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/field-values.md +0 -0
  214. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/fields.md +0 -0
  215. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/files.md +0 -0
  216. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/interactions.md +0 -0
  217. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/notes.md +0 -0
  218. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/relationships.md +0 -0
  219. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/reminders.md +0 -0
  220. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/webhooks.md +0 -0
  221. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/reference/types.md +0 -0
  222. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/docs/public/troubleshooting.md +0 -0
  223. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/examples/advanced_usage.py +0 -0
  224. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/examples/async_lifecycle.py +0 -0
  225. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/examples/basic_usage.py +0 -0
  226. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/examples/filter_builder.py +0 -0
  227. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/examples/hooks_debugging.py +0 -0
  228. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/examples/list_management.py +0 -0
  229. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/examples/resolve_helpers.py +0 -0
  230. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/examples/task_polling.py +0 -0
  231. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/.claude-plugin/.gitignore +0 -0
  232. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/.claude-plugin/.mcp.json +0 -0
  233. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/.claude-plugin/xaffinity-mcp.sh +0 -0
  234. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/.gitignore +0 -0
  235. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/Makefile +0 -0
  236. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/completions/entity-name.sh +0 -0
  237. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/completions/list-name.sh +0 -0
  238. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/completions/status-value.sh +0 -0
  239. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/docs/internal/debugging-improvements-plan.md +0 -0
  240. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/docs/internal/mcp-bash-progress-timeout-feature-request.md +0 -0
  241. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/icon.svg +0 -0
  242. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/lib/cache.sh +0 -0
  243. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/lib/cli-gateway.sh +0 -0
  244. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/lib/entity-types.sh +0 -0
  245. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/lib/field-resolution.sh +0 -0
  246. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/mcpb.conf +0 -0
  247. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/change-status/change-status.meta.json +0 -0
  248. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/change-status/change-status.txt +0 -0
  249. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/interaction-brief/interaction-brief.meta.json +0 -0
  250. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/interaction-brief/interaction-brief.txt +0 -0
  251. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/log-call/log-call.meta.json +0 -0
  252. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/log-call/log-call.txt +0 -0
  253. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/log-interaction-and-update-workflow/log-interaction-and-update-workflow.meta.json +0 -0
  254. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/log-interaction-and-update-workflow/log-interaction-and-update-workflow.txt +0 -0
  255. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/log-message/log-message.meta.json +0 -0
  256. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/log-message/log-message.txt +0 -0
  257. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/pipeline-review/pipeline-review.meta.json +0 -0
  258. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/pipeline-review/pipeline-review.txt +0 -0
  259. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/prepare-briefing/prepare-briefing.meta.json +0 -0
  260. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/prepare-briefing/prepare-briefing.txt +0 -0
  261. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/warm-intro/warm-intro.meta.json +0 -0
  262. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/prompts/warm-intro/warm-intro.txt +0 -0
  263. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/providers/xaffinity.sh +0 -0
  264. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/resources/data-model/data-model.meta.json +0 -0
  265. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/resources/interaction-enums/interaction-enums.json +0 -0
  266. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/resources/interaction-enums/interaction-enums.meta.json +0 -0
  267. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/resources/me/me.meta.json +0 -0
  268. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/resources/me/me.sh +0 -0
  269. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/resources/me-person-id/me-person-id.meta.json +0 -0
  270. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/resources/me-person-id/me-person-id.sh +0 -0
  271. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/resources/saved-views/saved-views.meta.json +0 -0
  272. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/resources/saved-views/saved-views.sh +0 -0
  273. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/resources/workflow-config/workflow-config.meta.json +0 -0
  274. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/resources/workflow-config/workflow-config.sh +0 -0
  275. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/server.d/env.sh +0 -0
  276. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/server.d/health-checks.sh +0 -0
  277. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/server.d/policy.sh +0 -0
  278. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/test/run.sh +0 -0
  279. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/test-progress.sh +0 -0
  280. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/tools/discover-commands/tool.meta.json +0 -0
  281. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/tools/discover-commands/tool.sh +0 -0
  282. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/tools/execute-write-command/tool.meta.json +0 -0
  283. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/tools/get-entity-dossier/tool.meta.json +0 -0
  284. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/tools/get-entity-dossier/tool.sh +0 -0
  285. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/tools/read-xaffinity-resource/tool.meta.json +0 -0
  286. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/tools/read-xaffinity-resource/tool.sh +0 -0
  287. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/xaffinity-mcp-env.sh +0 -0
  288. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mcp/xaffinity-mcp.sh +0 -0
  289. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/mkdocs.yml +0 -0
  290. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/plugins/affinity-sdk/.claude-plugin/skills/affinity-python-sdk/SKILL.md +0 -0
  291. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/plugins/xaffinity-cli/.claude-plugin/commands/affinity-help.md +0 -0
  292. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/plugins/xaffinity-cli/.claude-plugin/hooks/hooks.json +0 -0
  293. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/plugins/xaffinity-cli/.claude-plugin/hooks/pre-xaffinity.sh +0 -0
  294. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/plugins/xaffinity-cli/.claude-plugin/skills/xaffinity-cli-usage/SKILL.md +0 -0
  295. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/conftest.py +0 -0
  296. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/fixtures/webhooks/field_value_updated.json +0 -0
  297. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/fixtures/webhooks/list_entry_created.json +0 -0
  298. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/fixtures/webhooks/organization_created.json +0 -0
  299. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/fixtures/webhooks/organization_merged.json +0 -0
  300. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/fixtures/webhooks/person_created.json +0 -0
  301. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/fixtures/webhooks/unknown_event.json +0 -0
  302. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_affinity_client_wrapper_additional_coverage.py +0 -0
  303. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_async_file_download_streaming.py +0 -0
  304. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_column_limiting.py +0 -0
  305. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_command_context.py +0 -0
  306. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_company_cmds_coverage.py +0 -0
  307. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_config_cmds.py +0 -0
  308. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_date_params.py +0 -0
  309. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_date_utils.py +0 -0
  310. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_datetime_formatting.py +0 -0
  311. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_datetime_header_offsets.py +0 -0
  312. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_domain_linkification.py +0 -0
  313. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_entity_files_dump.py +0 -0
  314. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_entry_field.py +0 -0
  315. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_error_rendering.py +0 -0
  316. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_field_history.py +0 -0
  317. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_field_value_humanization.py +0 -0
  318. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_interaction_date_chunking.py +0 -0
  319. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_json_safety.py +0 -0
  320. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_list_cmds_coverage.py +0 -0
  321. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_missing_coverage.py +0 -0
  322. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_no_network_commands.py +0 -0
  323. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_opportunity_cmds_coverage.py +0 -0
  324. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_pager_logic.py +0 -0
  325. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_person_cmds_coverage.py +0 -0
  326. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_person_get.py +0 -0
  327. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_progress_manager.py +0 -0
  328. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_query_aggregates.py +0 -0
  329. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_query_dates.py +0 -0
  330. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_query_integration.py +0 -0
  331. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_query_planner.py +0 -0
  332. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_rate_limit_rendering.py +0 -0
  333. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_resolve_url_parsing.py +0 -0
  334. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_result_summary.py +0 -0
  335. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_serialization.py +0 -0
  336. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_session_cache.py +0 -0
  337. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_types.py +0 -0
  338. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_v1_only_cmds.py +0 -0
  339. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_cli_write_ops.py +0 -0
  340. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_client.py +0 -0
  341. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_env_helpers.py +0 -0
  342. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_exceptions_coverage.py +0 -0
  343. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_field_value_type.py +0 -0
  344. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_file_download_streaming.py +0 -0
  345. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_file_upload_helpers_and_validation.py +0 -0
  346. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_hooks.py +0 -0
  347. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_http_client_additional_coverage.py +0 -0
  348. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_http_client_remaining_coverage.py +0 -0
  349. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_inbound_webhooks.py +0 -0
  350. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_integration_smoke.py +0 -0
  351. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_interactions_and_files_regressions.py +0 -0
  352. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_isodatetime.py +0 -0
  353. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_list_entry_membership_and_opportunities.py +0 -0
  354. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_models.py +0 -0
  355. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_new_features.py +0 -0
  356. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_pagination_iterators.py +0 -0
  357. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_public_api.py +0 -0
  358. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_raw_pipeline_hook_events.py +0 -0
  359. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_requirements_additional.py +0 -0
  360. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_services_companies_coverage_gaps.py +0 -0
  361. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_services_lists_additional_coverage.py +0 -0
  362. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_services_lists_coverage_gaps.py +0 -0
  363. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_services_opportunities_additional_coverage.py +0 -0
  364. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_services_opportunities_coverage_gaps.py +0 -0
  365. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_services_opportunities_tasks_additional_coverage.py +0 -0
  366. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_services_persons_companies_additional_coverage.py +0 -0
  367. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_services_rate_limits_coverage_gaps.py +0 -0
  368. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_services_v1_only_async.py +0 -0
  369. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_services_v1_only_coverage_gaps.py +0 -0
  370. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_small_modules_coverage.py +0 -0
  371. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_transport_and_readonly_mode.py +0 -0
  372. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_v1_only_services_additional_coverage.py +0 -0
  373. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tests/test_v1_only_services_more_coverage.py +0 -0
  374. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tools/check_cli_patterns.py +0 -0
  375. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tools/generate_cli_commands_registry.py +0 -0
  376. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tools/generate_requirements_mapping.py +0 -0
  377. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tools/sync_mcp_registry.py +0 -0
  378. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tools/sync_mcp_version.py +0 -0
  379. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/tools/sync_plugin_version.py +0 -0
  380. {affinity_sdk-0.9.2 → affinity_sdk-0.9.9}/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()
@@ -5,8 +5,106 @@ 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
+ ## 0.9.9 - 2026-01-14
9
+
10
+ ### Added
11
+ - CLI: `query` command now supports advanced relationship filtering:
12
+ - `all` quantifier: Filter where all related items match a condition (e.g., find persons where all their companies have ".com" domains)
13
+ - `none` quantifier: Filter where no related items match a condition (e.g., find persons with no spam interactions)
14
+ - `exists` subquery: Filter where at least one related item exists, optionally matching a condition (e.g., find persons who have email interactions)
15
+ - `_count` pseudo-field: Filter by count of related items (e.g., `"path": "companies._count", "op": "gte", "value": 2`)
16
+ - Available relationship paths: persons→companies/opportunities/interactions/notes/listEntries, companies→persons/opportunities/interactions/notes/listEntries, opportunities→persons/companies/interactions
17
+ - Note: These features cause N+1 API calls to fetch relationship data; use `--dry-run` to preview
18
+
19
+ ### Changed (Breaking)
20
+ - CLI: Renamed relationship `"people"` to `"persons"` for consistency with entity type names:
21
+ - Query `include`: `{"from": "companies", "include": ["people"]}` → use `["persons"]`
22
+ - CLI `--expand`: `xaffinity company get <id> --expand people` → use `--expand persons`
23
+ - JSON output: `data.people` → `data.persons`
24
+
25
+ ### Fixed
26
+ - 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)
27
+
28
+ ## 0.9.8 - 2026-01-12
29
+
30
+ ### Fixed
31
+ - 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:
32
+ - With filters: Empty results when matching records were beyond the limit position
33
+ - With sort + limit: Random N records sorted instead of actual top N
34
+ - With aggregate: Inaccurate counts/sums computed on partial data
35
+
36
+ ## 0.9.7 - 2026-01-12
37
+
38
+ ### Fixed
39
+ - CI: Smoke test now correctly installs CLI extras before testing CLI import
40
+
41
+ ## 0.9.6 - 2026-01-12
42
+
43
+ ### Added
44
+ - CLI: `listEntries` queries now include convenience aliases: `listEntryId`, `entityId`, `entityName`, `entityType`. These intuitive field names work in both `select` and `where` clauses.
45
+ - CLI: `listEntries` records now always include a `fields` key (defaults to `{}` if no custom fields).
46
+
47
+ ### Changed
48
+ - 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}}`.
49
+
50
+ ## 0.9.5 - 2026-01-12
51
+
52
+ ### Added
53
+ - CLI: New `--output`/`-o` option supporting multiple formats: `json`, `jsonl`, `markdown`, `toon`, `csv`, `table` (default).
54
+ - `markdown`: GitHub-flavored markdown tables, best for LLM analysis and comprehension
55
+ - `toon`: Token-Optimized Object Notation, 30-60% fewer tokens than JSON for large datasets
56
+ - `jsonl`: JSON Lines format, one object per line for streaming workflows
57
+ - Example: `xaffinity person ls --output markdown`, `xaffinity query -o toon`
58
+ - Existing `--csv` and `--json` flags continue to work as before.
59
+
60
+ ### Changed
61
+ - 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.
62
+
63
+ ### Fixed
64
+ - 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.
65
+
66
+ ## 0.9.4 - 2026-01-12
67
+
68
+ ### Added
69
+ - CLI: `query` command now supports `has_any` and `has_all` operators for multi-select field filtering.
70
+ - SDK/CLI: Filter parser now supports V2 API comparison operators: `>`, `>=`, `<`, `<=` for numeric/date comparisons.
71
+ - SDK/CLI: Filter parser now supports word-based operator aliases for LLM/human clarity:
72
+ - `contains`, `starts_with`, `ends_with` (string matching)
73
+ - `gt`, `gte`, `lt`, `lte` (numeric/date comparisons)
74
+ - `is null`, `is not null`, `is empty` (null/empty checks)
75
+ - SDK/CLI: Filter parser now supports collection bracket syntax `[A, B, C]` with operators:
76
+ - `in [A, B]` - value is one of the listed values
77
+ - `between [1, 10]` - value is in range (inclusive)
78
+ - `has_any [A, B]` - array field contains any of the values
79
+ - `has_all [A, B]` - array field contains all of the values
80
+ - `contains_any [A, B]` - substring match for any term
81
+ - `contains_all [A, B]` - substring match for all terms
82
+ - `= [A, B]` - set equality (array has exactly these elements)
83
+ - `=~ [A, B]` - V2 API collection contains (array contains all elements)
84
+
85
+ ### Fixed
86
+ - 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.
87
+ - 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.
88
+ - SDK/CLI: Fixed `=^` (starts_with) and `=$` (ends_with) operators which were broken due to tokenizer ordering issue.
89
+
90
+ ### Improved
91
+ - SDK/CLI: Filter parser now provides helpful hints for common mistakes:
92
+ - Multi-word field names: suggests quoting (`"Team Member"`)
93
+ - Multi-word values: suggests quoting (`"Intro Meeting"`)
94
+ - SQL keywords (`AND`, `OR`): suggests correct symbols (`&`, `|`)
95
+ - Double equals (`==`): suggests single `=`
96
+
97
+ ## 0.9.3 - 2026-01-11
98
+
99
+ ### Changed
100
+ - CI: SDK releases now include MCPB bundle and plugin ZIP for convenience.
101
+ - CI: Enabled PyPI attestations via workflow_dispatch API trigger.
102
+
8
103
  ## 0.9.2 - 2026-01-11
9
104
 
105
+ ### Fixed
106
+ - SDK: `AsyncListEntryService.pages()` now supports `progress_callback` parameter (sync/async parity fix).
107
+
10
108
  ### Changed
11
109
  - **BREAKING**: CLI: `interaction ls` JSON output restructured for consistency:
12
110
  - `.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.9
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"]
@@ -1066,7 +1066,7 @@ def company_files_upload(
1066
1066
  "--expand",
1067
1067
  "expand",
1068
1068
  multiple=True,
1069
- type=click.Choice(["lists", "list-entries", "people"]),
1069
+ type=click.Choice(["lists", "list-entries", "persons"]),
1070
1070
  help="Include related data (repeatable).",
1071
1071
  )
1072
1072
  @click.option(
@@ -1452,26 +1452,26 @@ def company_get(
1452
1452
  )
1453
1453
  data["listEntries"] = entries_items
1454
1454
 
1455
- if "people" in expand_set:
1456
- people_cap = max_results
1457
- if people_cap is None and not all_pages:
1458
- people_cap = 100
1459
- if people_cap is not None and people_cap <= 0:
1460
- data["people"] = []
1455
+ if "persons" in expand_set:
1456
+ persons_cap = max_results
1457
+ if persons_cap is None and not all_pages:
1458
+ persons_cap = 100
1459
+ if persons_cap is not None and persons_cap <= 0:
1460
+ data["persons"] = []
1461
1461
  else:
1462
1462
  person_ids = client.companies.get_associated_person_ids(company_id)
1463
- total_people = len(person_ids)
1464
- if people_cap is not None and total_people > people_cap:
1463
+ total_persons = len(person_ids)
1464
+ if persons_cap is not None and total_persons > persons_cap:
1465
1465
  warnings.append(
1466
- f"People truncated at {people_cap:,} items; re-run with --all "
1466
+ f"Persons truncated at {persons_cap:,} items; re-run with --all "
1467
1467
  "or a higher --max-results to fetch more."
1468
1468
  )
1469
1469
 
1470
- people = client.companies.get_associated_people(
1470
+ persons = client.companies.get_associated_people(
1471
1471
  company_id,
1472
- max_results=people_cap,
1472
+ max_results=persons_cap,
1473
1473
  )
1474
- data["people"] = [
1474
+ data["persons"] = [
1475
1475
  {
1476
1476
  "id": int(person.id),
1477
1477
  "name": person.full_name,
@@ -1484,7 +1484,7 @@ def company_get(
1484
1484
  else None
1485
1485
  ),
1486
1486
  }
1487
- for person in people
1487
+ for person in persons
1488
1488
  ]
1489
1489
 
1490
1490
  if "list-entries" in expand_set and entries_items and ctx.output != "json":