affinity-sdk 0.4.7__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.
- affinity_sdk-0.9.9/.claude-plugin/marketplace.json +26 -0
- affinity_sdk-0.9.9/.github/PULL_REQUEST_TEMPLATE/release.md +31 -0
- affinity_sdk-0.9.9/.github/workflows/ci.yml +134 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.github/workflows/docs.yml +9 -5
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.github/workflows/labels.yml +1 -1
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.github/workflows/linkcheck.yml +2 -2
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.github/workflows/openapi-validation.yml +2 -2
- affinity_sdk-0.9.9/.github/workflows/plugin-build.yml +106 -0
- affinity_sdk-0.9.9/.github/workflows/plugin-release.yml +163 -0
- affinity_sdk-0.9.9/.github/workflows/release-detect.yml +135 -0
- affinity_sdk-0.9.9/.github/workflows/release.yml +337 -0
- affinity_sdk-0.9.9/.github/workflows/version-check.yml +92 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.gitignore +2 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.pre-commit-config.yaml +16 -3
- affinity_sdk-0.9.9/CHANGELOG.md +465 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/CONTRIBUTING.md +61 -7
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/PKG-INFO +53 -15
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/README.md +49 -11
- affinity_sdk-0.9.9/VERSIONING.md +182 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/__init__.py +2 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/__init__.py +4 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/_entity_files_dump.py +3 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/_v1_parsing.py +28 -3
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/company_cmds.py +601 -562
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/completion_cmd.py +2 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/config_cmds.py +69 -34
- affinity_sdk-0.9.9/affinity/cli/commands/entry_cmds.py +33 -0
- affinity_sdk-0.9.9/affinity/cli/commands/field_cmds.py +413 -0
- affinity_sdk-0.9.9/affinity/cli/commands/interaction_cmds.py +875 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/list_cmds.py +906 -486
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/note_cmds.py +144 -27
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/opportunity_cmds.py +417 -388
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/person_cmds.py +597 -548
- affinity_sdk-0.9.9/affinity/cli/commands/query_cmd.py +481 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/relationship_strength_cmds.py +23 -5
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/reminder_cmds.py +184 -39
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/resolve_url_cmd.py +3 -1
- affinity_sdk-0.9.9/affinity/cli/commands/session_cmds.py +84 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/task_cmds.py +31 -4
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/version_cmd.py +2 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/whoami_cmd.py +11 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/context.py +33 -3
- affinity_sdk-0.9.9/affinity/cli/csv_utils.py +195 -0
- affinity_sdk-0.9.9/affinity/cli/date_utils.py +42 -0
- affinity_sdk-0.9.9/affinity/cli/decorators.py +77 -0
- affinity_sdk-0.9.9/affinity/cli/formatters.py +551 -0
- affinity_sdk-0.9.9/affinity/cli/help_json.py +283 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/main.py +94 -17
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/options.py +9 -2
- affinity_sdk-0.9.9/affinity/cli/progress.py +183 -0
- affinity_sdk-0.9.9/affinity/cli/query/__init__.py +163 -0
- affinity_sdk-0.9.9/affinity/cli/query/aggregates.py +357 -0
- affinity_sdk-0.9.9/affinity/cli/query/dates.py +194 -0
- affinity_sdk-0.9.9/affinity/cli/query/exceptions.py +147 -0
- affinity_sdk-0.9.9/affinity/cli/query/executor.py +1977 -0
- affinity_sdk-0.9.9/affinity/cli/query/filters.py +700 -0
- affinity_sdk-0.9.9/affinity/cli/query/models.py +335 -0
- affinity_sdk-0.9.9/affinity/cli/query/output.py +339 -0
- affinity_sdk-0.9.9/affinity/cli/query/parser.py +619 -0
- affinity_sdk-0.9.9/affinity/cli/query/planner.py +538 -0
- affinity_sdk-0.9.9/affinity/cli/query/progress.py +270 -0
- affinity_sdk-0.9.9/affinity/cli/query/schema.py +472 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/render.py +440 -45
- affinity_sdk-0.9.9/affinity/cli/resolve.py +222 -0
- affinity_sdk-0.9.9/affinity/cli/results.py +308 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/runner.py +92 -26
- affinity_sdk-0.9.9/affinity/cli/session_cache.py +276 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/client.py +4 -2
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/clients/http.py +1 -1
- affinity_sdk-0.9.9/affinity/compare.py +501 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/exceptions.py +22 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/filters.py +425 -33
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/inbound_webhooks.py +7 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/models/entities.py +5 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/models/pagination.py +19 -1
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/models/types.py +42 -6
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/services/companies.py +103 -9
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/services/lists.py +314 -63
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/services/opportunities.py +254 -17
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/services/persons.py +203 -9
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/services/v1_only.py +17 -0
- affinity_sdk-0.9.9/codecov.yml +25 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/cli-development-guide.md +2 -2
- affinity_sdk-0.9.9/docs/public/ai-integrations/index.md +77 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/cli/commands.md +212 -97
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/cli/index.md +30 -0
- affinity_sdk-0.9.9/docs/public/cli/scripting.md +151 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/cli-reference.md +69 -8
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/getting-started.md +1 -1
- affinity_sdk-0.9.9/docs/public/guides/claude-code-plugins.md +148 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/csv-export.md +51 -32
- affinity_sdk-0.9.9/docs/public/guides/datetime-handling.md +100 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/filtering.md +97 -34
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/performance.md +12 -0
- affinity_sdk-0.9.9/docs/public/guides/query-command.md +498 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/index.md +1 -0
- affinity_sdk-0.9.9/docs/public/mcp/index.md +376 -0
- affinity_sdk-0.9.9/docs/public/reference/query-language.md +631 -0
- affinity_sdk-0.9.9/mcp/.claude-plugin/.gitignore +14 -0
- affinity_sdk-0.9.9/mcp/.claude-plugin/.mcp.json +6 -0
- affinity_sdk-0.9.9/mcp/.claude-plugin/plugin.json +26 -0
- affinity_sdk-0.9.9/mcp/.claude-plugin/skills/affinity-mcp-workflows/SKILL.md +225 -0
- affinity_sdk-0.9.9/mcp/.claude-plugin/skills/query-language/SKILL.md +629 -0
- affinity_sdk-0.9.9/mcp/.claude-plugin/xaffinity-mcp.sh +107 -0
- affinity_sdk-0.9.9/mcp/.gitignore +22 -0
- affinity_sdk-0.9.9/mcp/.registry/commands-metadata.json +109 -0
- affinity_sdk-0.9.9/mcp/.registry/commands.json +3018 -0
- affinity_sdk-0.9.9/mcp/.registry/prompts.json +253 -0
- affinity_sdk-0.9.9/mcp/.registry/resource-templates.json +30 -0
- affinity_sdk-0.9.9/mcp/.registry/resources.json +41 -0
- affinity_sdk-0.9.9/mcp/CHANGELOG.md +383 -0
- affinity_sdk-0.9.9/mcp/COMPATIBILITY +45 -0
- affinity_sdk-0.9.9/mcp/Makefile +120 -0
- affinity_sdk-0.9.9/mcp/README.md +352 -0
- affinity_sdk-0.9.9/mcp/VERSION +1 -0
- affinity_sdk-0.9.9/mcp/completions/entity-name.sh +51 -0
- affinity_sdk-0.9.9/mcp/completions/list-name.sh +42 -0
- affinity_sdk-0.9.9/mcp/completions/status-value.sh +46 -0
- affinity_sdk-0.9.9/mcp/docs/DEBUGGING.md +152 -0
- affinity_sdk-0.9.9/mcp/docs/internal/debugging-improvements-plan.md +375 -0
- affinity_sdk-0.9.9/mcp/docs/internal/mcp-bash-progress-timeout-feature-request.md +215 -0
- affinity_sdk-0.9.9/mcp/icon.svg +19 -0
- affinity_sdk-0.9.9/mcp/lib/cache.sh +124 -0
- affinity_sdk-0.9.9/mcp/lib/cli-gateway.sh +451 -0
- affinity_sdk-0.9.9/mcp/lib/common.sh +494 -0
- affinity_sdk-0.9.9/mcp/lib/entity-types.sh +84 -0
- affinity_sdk-0.9.9/mcp/lib/field-resolution.sh +124 -0
- affinity_sdk-0.9.9/mcp/mcp-bash.lock +5 -0
- affinity_sdk-0.9.9/mcp/mcpb.conf +24 -0
- affinity_sdk-0.9.9/mcp/prompts/change-status/change-status.meta.json +26 -0
- affinity_sdk-0.9.9/mcp/prompts/change-status/change-status.txt +13 -0
- affinity_sdk-0.9.9/mcp/prompts/interaction-brief/interaction-brief.meta.json +19 -0
- affinity_sdk-0.9.9/mcp/prompts/interaction-brief/interaction-brief.txt +13 -0
- affinity_sdk-0.9.9/mcp/prompts/log-call/log-call.meta.json +32 -0
- affinity_sdk-0.9.9/mcp/prompts/log-call/log-call.txt +16 -0
- affinity_sdk-0.9.9/mcp/prompts/log-interaction-and-update-workflow/log-interaction-and-update-workflow.meta.json +27 -0
- affinity_sdk-0.9.9/mcp/prompts/log-interaction-and-update-workflow/log-interaction-and-update-workflow.txt +16 -0
- affinity_sdk-0.9.9/mcp/prompts/log-message/log-message.meta.json +33 -0
- affinity_sdk-0.9.9/mcp/prompts/log-message/log-message.txt +16 -0
- affinity_sdk-0.9.9/mcp/prompts/pipeline-review/pipeline-review.meta.json +14 -0
- affinity_sdk-0.9.9/mcp/prompts/pipeline-review/pipeline-review.txt +17 -0
- affinity_sdk-0.9.9/mcp/prompts/prepare-briefing/prepare-briefing.meta.json +19 -0
- affinity_sdk-0.9.9/mcp/prompts/prepare-briefing/prepare-briefing.txt +16 -0
- affinity_sdk-0.9.9/mcp/prompts/warm-intro/warm-intro.meta.json +18 -0
- affinity_sdk-0.9.9/mcp/prompts/warm-intro/warm-intro.txt +17 -0
- affinity_sdk-0.9.9/mcp/providers/xaffinity.sh +107 -0
- affinity_sdk-0.9.9/mcp/resources/data-model/data-model.md +211 -0
- affinity_sdk-0.9.9/mcp/resources/data-model/data-model.meta.json +7 -0
- affinity_sdk-0.9.9/mcp/resources/field-catalogs/field-catalogs.meta.json +7 -0
- affinity_sdk-0.9.9/mcp/resources/field-catalogs/field-catalogs.sh +91 -0
- affinity_sdk-0.9.9/mcp/resources/interaction-enums/interaction-enums.json +13 -0
- affinity_sdk-0.9.9/mcp/resources/interaction-enums/interaction-enums.meta.json +7 -0
- affinity_sdk-0.9.9/mcp/resources/me/me.meta.json +7 -0
- affinity_sdk-0.9.9/mcp/resources/me/me.sh +16 -0
- affinity_sdk-0.9.9/mcp/resources/me-person-id/me-person-id.meta.json +7 -0
- affinity_sdk-0.9.9/mcp/resources/me-person-id/me-person-id.sh +29 -0
- affinity_sdk-0.9.9/mcp/resources/saved-views/saved-views.meta.json +7 -0
- affinity_sdk-0.9.9/mcp/resources/saved-views/saved-views.sh +28 -0
- affinity_sdk-0.9.9/mcp/resources/workflow-config/workflow-config.meta.json +7 -0
- affinity_sdk-0.9.9/mcp/resources/workflow-config/workflow-config.sh +47 -0
- affinity_sdk-0.9.9/mcp/scripts/install-framework.sh +80 -0
- affinity_sdk-0.9.9/mcp/server.d/env.sh +74 -0
- affinity_sdk-0.9.9/mcp/server.d/health-checks.sh +32 -0
- affinity_sdk-0.9.9/mcp/server.d/policy.sh +32 -0
- affinity_sdk-0.9.9/mcp/server.d/requirements.json +29 -0
- affinity_sdk-0.9.9/mcp/server.d/server.meta.json +6 -0
- affinity_sdk-0.9.9/mcp/test/README.md +136 -0
- affinity_sdk-0.9.9/mcp/test/run.sh +450 -0
- affinity_sdk-0.9.9/mcp/test-progress.sh +254 -0
- affinity_sdk-0.9.9/mcp/tools/discover-commands/tool.meta.json +46 -0
- affinity_sdk-0.9.9/mcp/tools/discover-commands/tool.sh +152 -0
- affinity_sdk-0.9.9/mcp/tools/execute-read-command/tool.meta.json +42 -0
- affinity_sdk-0.9.9/mcp/tools/execute-read-command/tool.sh +176 -0
- affinity_sdk-0.9.9/mcp/tools/execute-write-command/tool.meta.json +36 -0
- affinity_sdk-0.9.9/mcp/tools/execute-write-command/tool.sh +227 -0
- affinity_sdk-0.9.9/mcp/tools/get-entity-dossier/tool.meta.json +46 -0
- affinity_sdk-0.9.9/mcp/tools/get-entity-dossier/tool.sh +131 -0
- affinity_sdk-0.9.9/mcp/tools/query/tool.meta.json +100 -0
- affinity_sdk-0.9.9/mcp/tools/query/tool.sh +106 -0
- affinity_sdk-0.9.9/mcp/tools/read-xaffinity-resource/tool.meta.json +19 -0
- affinity_sdk-0.9.9/mcp/tools/read-xaffinity-resource/tool.sh +23 -0
- affinity_sdk-0.9.9/mcp/xaffinity-mcp-env.sh +37 -0
- affinity_sdk-0.9.9/mcp/xaffinity-mcp.sh +178 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/mkdocs.yml +5 -2
- affinity_sdk-0.9.9/plugins/affinity-sdk/.claude-plugin/plugin.json +22 -0
- affinity_sdk-0.4.7/.claude-plugin/skills/querying-affinity-crm/SDK_REFERENCE.md → affinity_sdk-0.9.9/plugins/affinity-sdk/.claude-plugin/skills/affinity-python-sdk/SKILL.md +101 -72
- affinity_sdk-0.9.9/plugins/xaffinity-cli/.claude-plugin/commands/affinity-help.md +56 -0
- affinity_sdk-0.9.9/plugins/xaffinity-cli/.claude-plugin/plugin.json +28 -0
- affinity_sdk-0.9.9/plugins/xaffinity-cli/.claude-plugin/skills/xaffinity-cli-usage/SKILL.md +193 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/pyproject.toml +11 -4
- affinity_sdk-0.9.9/tests/cli/test_formatters.py +566 -0
- affinity_sdk-0.9.9/tests/cli/test_output_formats_integration.py +376 -0
- affinity_sdk-0.9.9/tests/test_cli_column_limiting.py +199 -0
- affinity_sdk-0.9.9/tests/test_cli_command_context.py +257 -0
- affinity_sdk-0.9.9/tests/test_cli_company_cmds_coverage.py +278 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_company_get.py +22 -9
- affinity_sdk-0.9.9/tests/test_cli_csv_export.py +1012 -0
- affinity_sdk-0.9.9/tests/test_cli_date_params.py +154 -0
- affinity_sdk-0.9.9/tests/test_cli_date_utils.py +82 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_datetime_formatting.py +1 -1
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_datetime_header_offsets.py +1 -1
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_domain_linkification.py +1 -1
- affinity_sdk-0.9.9/tests/test_cli_entry_field.py +1317 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_error_rendering.py +16 -4
- affinity_sdk-0.9.9/tests/test_cli_field_history.py +202 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_field_value_humanization.py +6 -6
- affinity_sdk-0.9.9/tests/test_cli_interaction_date_chunking.py +1044 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_json_safety.py +1 -1
- affinity_sdk-0.9.9/tests/test_cli_list_cmds_coverage.py +519 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_no_network_commands.py +2 -2
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_opportunity_cmds.py +15 -14
- affinity_sdk-0.9.9/tests/test_cli_opportunity_cmds_coverage.py +155 -0
- affinity_sdk-0.9.9/tests/test_cli_person_cmds_coverage.py +348 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_person_get.py +1 -1
- affinity_sdk-0.9.9/tests/test_cli_progress_manager.py +164 -0
- affinity_sdk-0.9.9/tests/test_cli_query_aggregates.py +481 -0
- affinity_sdk-0.9.9/tests/test_cli_query_cmd.py +401 -0
- affinity_sdk-0.9.9/tests/test_cli_query_dates.py +205 -0
- affinity_sdk-0.9.9/tests/test_cli_query_executor.py +3850 -0
- affinity_sdk-0.9.9/tests/test_cli_query_filters.py +1354 -0
- affinity_sdk-0.9.9/tests/test_cli_query_integration.py +240 -0
- affinity_sdk-0.9.9/tests/test_cli_query_parser.py +869 -0
- affinity_sdk-0.9.9/tests/test_cli_query_planner.py +625 -0
- affinity_sdk-0.9.9/tests/test_cli_query_safety.py +258 -0
- affinity_sdk-0.9.9/tests/test_cli_query_schema.py +443 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_rate_limit_rendering.py +2 -2
- affinity_sdk-0.9.9/tests/test_cli_result_summary.py +237 -0
- affinity_sdk-0.9.9/tests/test_cli_session_cache.py +389 -0
- affinity_sdk-0.9.9/tests/test_cli_types.py +152 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_v1_only_cmds.py +21 -10
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_write_ops.py +14 -13
- affinity_sdk-0.9.9/tests/test_compare.py +518 -0
- affinity_sdk-0.9.9/tests/test_exceptions_coverage.py +341 -0
- affinity_sdk-0.9.9/tests/test_filters.py +1071 -0
- affinity_sdk-0.9.9/tests/test_hooks.py +404 -0
- affinity_sdk-0.9.9/tests/test_isodatetime.py +433 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_models.py +4 -2
- affinity_sdk-0.9.9/tests/test_public_api.py +215 -0
- affinity_sdk-0.9.9/tests/test_services_companies_coverage_gaps.py +460 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_services_lists_additional_coverage.py +6 -8
- affinity_sdk-0.9.9/tests/test_services_lists_coverage_gaps.py +402 -0
- affinity_sdk-0.9.9/tests/test_services_opportunities_coverage_gaps.py +339 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_services_persons_companies_additional_coverage.py +519 -0
- affinity_sdk-0.9.9/tests/test_services_rate_limits_coverage_gaps.py +287 -0
- affinity_sdk-0.9.9/tests/test_services_v1_only_coverage_gaps.py +336 -0
- affinity_sdk-0.9.9/tools/generate_cli_commands_registry.py +200 -0
- affinity_sdk-0.9.9/tools/sync_mcp_registry.py +136 -0
- affinity_sdk-0.9.9/tools/sync_mcp_version.py +63 -0
- affinity_sdk-0.9.9/tools/sync_plugin_version.py +69 -0
- affinity_sdk-0.9.9/uv.lock +1485 -0
- affinity_sdk-0.4.7/.claude-plugin/commands/affinity-help.md +0 -58
- affinity_sdk-0.4.7/.claude-plugin/marketplace.json +0 -16
- affinity_sdk-0.4.7/.claude-plugin/plugin.json +0 -27
- affinity_sdk-0.4.7/.claude-plugin/skills/querying-affinity-crm/CLI_REFERENCE.md +0 -349
- affinity_sdk-0.4.7/.claude-plugin/skills/querying-affinity-crm/LIST_EXPORT_EXPAND.md +0 -177
- affinity_sdk-0.4.7/.claude-plugin/skills/querying-affinity-crm/SKILL.md +0 -213
- affinity_sdk-0.4.7/.github/workflows/ci.yml +0 -56
- affinity_sdk-0.4.7/.github/workflows/release.yml +0 -178
- affinity_sdk-0.4.7/CHANGELOG.md +0 -94
- affinity_sdk-0.4.7/affinity/cli/commands/field_cmds.py +0 -135
- affinity_sdk-0.4.7/affinity/cli/commands/interaction_cmds.py +0 -384
- affinity_sdk-0.4.7/affinity/cli/csv_utils.py +0 -120
- affinity_sdk-0.4.7/affinity/cli/progress.py +0 -99
- affinity_sdk-0.4.7/affinity/cli/resolve.py +0 -114
- affinity_sdk-0.4.7/affinity/cli/results.py +0 -44
- affinity_sdk-0.4.7/docs/public/cli/scripting.md +0 -41
- affinity_sdk-0.4.7/docs/public/guides/claude-code-plugin.md +0 -86
- affinity_sdk-0.4.7/docs/public/guides/v1-v2-routing.md +0 -3
- affinity_sdk-0.4.7/tests/test_cli_csv_export.py +0 -2770
- affinity_sdk-0.4.7/tests/test_cli_progress_manager.py +0 -9
- affinity_sdk-0.4.7/tests/test_filters.py +0 -390
- affinity_sdk-0.4.7/tools/sync_plugin_version.py +0 -48
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.editorconfig +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.env.example +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.gitattributes +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.github/CODEOWNERS +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.github/PULL_REQUEST_TEMPLATE/cli_command.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.github/dependabot.yml +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.github/labels.yml +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/.github/pull_request_template.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/CODE_OF_CONDUCT.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/LICENSE +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/SECURITY.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/click_compat.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/__init__.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/commands/_list_entry_fields.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/config.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/errors.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/field_utils.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/logging.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/paths.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/resolvers.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/serialization.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/cli/types.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/clients/__init__.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/clients/pipeline.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/downloads.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/hooks.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/models/__init__.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/models/rate_limit_snapshot.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/models/secondary.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/policies.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/progress.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/py.typed +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/services/__init__.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/services/rate_limits.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/services/tasks.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/affinity/types.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/changelog.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/examples.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/glossary.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/api-versions-and-routing.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/authentication.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/configuration.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/debugging-hooks.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/errors-and-retries.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/field-types-and-values.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/field-values.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/ids-and-types.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/models.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/opportunity-associations.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/pagination.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/rate-limits.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/sync-vs-async.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/guides/webhooks.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/client.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/exceptions.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/filters.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/models.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/services/companies.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/services/lists.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/services/opportunities.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/services/persons.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/services/tasks.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/auth.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/field-values.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/fields.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/files.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/interactions.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/notes.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/relationships.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/reminders.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/services/v1/webhooks.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/reference/types.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/docs/public/troubleshooting.md +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/examples/advanced_usage.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/examples/async_lifecycle.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/examples/basic_usage.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/examples/filter_builder.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/examples/hooks_debugging.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/examples/list_management.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/examples/resolve_helpers.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/examples/task_polling.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9/plugins/xaffinity-cli}/.claude-plugin/hooks/hooks.json +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9/plugins/xaffinity-cli}/.claude-plugin/hooks/pre-xaffinity.sh +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/conftest.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/fixtures/webhooks/field_value_updated.json +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/fixtures/webhooks/list_entry_created.json +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/fixtures/webhooks/organization_created.json +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/fixtures/webhooks/organization_merged.json +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/fixtures/webhooks/person_created.json +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/fixtures/webhooks/unknown_event.json +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_affinity_client_wrapper_additional_coverage.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_async_file_download_streaming.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_config_cmds.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_entity_files_dump.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_missing_coverage.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_pager_logic.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_resolve_url_parsing.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_cli_serialization.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_client.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_env_helpers.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_field_value_type.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_file_download_streaming.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_file_upload_helpers_and_validation.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_http_client_additional_coverage.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_http_client_remaining_coverage.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_inbound_webhooks.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_integration_smoke.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_interactions_and_files_regressions.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_list_entry_membership_and_opportunities.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_new_features.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_pagination_iterators.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_raw_pipeline_hook_events.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_requirements_additional.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_services_opportunities_additional_coverage.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_services_opportunities_tasks_additional_coverage.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_services_v1_only_async.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_small_modules_coverage.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_transport_and_readonly_mode.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_v1_only_services_additional_coverage.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tests/test_v1_only_services_more_coverage.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tools/check_cli_patterns.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tools/generate_requirements_mapping.py +0 -0
- {affinity_sdk-0.4.7 → affinity_sdk-0.9.9}/tools/validate_openapi_models.py +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "xaffinity",
|
|
3
|
+
"owner": {
|
|
4
|
+
"name": "Yaniv Golan"
|
|
5
|
+
},
|
|
6
|
+
"metadata": {
|
|
7
|
+
"description": "Plugins for Affinity CRM - Python SDK, CLI, and MCP integrations"
|
|
8
|
+
},
|
|
9
|
+
"plugins": [
|
|
10
|
+
{
|
|
11
|
+
"name": "sdk",
|
|
12
|
+
"source": "./plugins/affinity-sdk/.claude-plugin",
|
|
13
|
+
"description": "Python SDK for Affinity CRM - typed IDs, async support, pagination patterns for developers"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"name": "cli",
|
|
17
|
+
"source": "./plugins/xaffinity-cli/.claude-plugin",
|
|
18
|
+
"description": "Command-line interface for Affinity CRM - search, export, filter CRM data via xaffinity commands"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "mcp",
|
|
22
|
+
"source": "./mcp/.claude-plugin",
|
|
23
|
+
"description": "MCP server for Affinity CRM - workflow tools, relationship intelligence, pipeline management"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Release
|
|
3
|
+
about: Checklist for SDK or MCP releases
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Release Type
|
|
7
|
+
|
|
8
|
+
- [ ] SDK Release (vX.Y.Z)
|
|
9
|
+
- [ ] MCP Release (plugin-vX.Y.Z)
|
|
10
|
+
|
|
11
|
+
## SDK Release Checklist (vX.Y.Z)
|
|
12
|
+
|
|
13
|
+
- [ ] Version bumped in `pyproject.toml`
|
|
14
|
+
- [ ] Plugin versions synced (pre-commit should handle)
|
|
15
|
+
- [ ] `CHANGELOG.md` updated with breaking changes noted
|
|
16
|
+
- [ ] If CLI output format changed: MCP `COMPATIBILITY` updated
|
|
17
|
+
- [ ] Tests pass locally and in CI
|
|
18
|
+
|
|
19
|
+
## MCP Release Checklist (plugin-vX.Y.Z)
|
|
20
|
+
|
|
21
|
+
- [ ] Version bumped in `mcp/VERSION`
|
|
22
|
+
- [ ] `mcp/.claude-plugin/plugin.json` version updated
|
|
23
|
+
- [ ] `mcp/mcpb.conf` MCPB_VERSION updated
|
|
24
|
+
- [ ] `mcp/COMPATIBILITY` CLI requirements updated if needed
|
|
25
|
+
- [ ] `mcp/CHANGELOG.md` documents CLI compatibility
|
|
26
|
+
- [ ] Builds successfully: `cd mcp && make all verify`
|
|
27
|
+
|
|
28
|
+
## Post-Merge
|
|
29
|
+
|
|
30
|
+
- [ ] Tag pushed: `git tag vX.Y.Z && git push --tags` (SDK)
|
|
31
|
+
- [ ] Tag pushed: `git tag plugin-vX.Y.Z && git push --tags` (MCP)
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
mcp-plugin:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v6
|
|
12
|
+
|
|
13
|
+
- name: Build MCP plugin
|
|
14
|
+
run: make -C mcp plugin
|
|
15
|
+
|
|
16
|
+
- name: Verify plugin structure
|
|
17
|
+
run: |
|
|
18
|
+
# Ensure critical files exist after build (ZIP-based distribution)
|
|
19
|
+
make -C mcp verify
|
|
20
|
+
test -f mcp/.claude-plugin/xaffinity-mcp.sh
|
|
21
|
+
test -f mcp/.claude-plugin/plugin.json
|
|
22
|
+
test -f mcp/.claude-plugin/xaffinity-mcp-plugin.zip
|
|
23
|
+
test -f mcp/.claude-plugin/VERSION
|
|
24
|
+
echo "Plugin structure validated successfully"
|
|
25
|
+
|
|
26
|
+
- name: Test ZIP extraction
|
|
27
|
+
run: |
|
|
28
|
+
cd mcp/.claude-plugin
|
|
29
|
+
mkdir -p .mcp-extracted
|
|
30
|
+
unzip -q xaffinity-mcp-plugin.zip -d .mcp-extracted
|
|
31
|
+
test -x .mcp-extracted/xaffinity-mcp.sh
|
|
32
|
+
test -d .mcp-extracted/tools
|
|
33
|
+
test -d .mcp-extracted/prompts
|
|
34
|
+
echo "ZIP extraction test passed"
|
|
35
|
+
|
|
36
|
+
test:
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
strategy:
|
|
39
|
+
fail-fast: false
|
|
40
|
+
matrix:
|
|
41
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
42
|
+
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v6
|
|
45
|
+
|
|
46
|
+
- name: Set up Python
|
|
47
|
+
uses: actions/setup-python@v6
|
|
48
|
+
with:
|
|
49
|
+
python-version: ${{ matrix.python-version }}
|
|
50
|
+
cache: pip
|
|
51
|
+
cache-dependency-path: pyproject.toml
|
|
52
|
+
|
|
53
|
+
- name: Install
|
|
54
|
+
run: |
|
|
55
|
+
python -m pip install --upgrade pip
|
|
56
|
+
python -m pip install -e ".[dev]"
|
|
57
|
+
|
|
58
|
+
- name: Lint
|
|
59
|
+
run: |
|
|
60
|
+
ruff format --check .
|
|
61
|
+
ruff check .
|
|
62
|
+
|
|
63
|
+
- name: Type check
|
|
64
|
+
run: |
|
|
65
|
+
mypy affinity
|
|
66
|
+
|
|
67
|
+
- name: Test
|
|
68
|
+
run: |
|
|
69
|
+
pytest --cov=affinity --cov-report=term-missing --cov-report=xml
|
|
70
|
+
|
|
71
|
+
- name: Upload coverage to Codecov
|
|
72
|
+
uses: codecov/codecov-action@v5
|
|
73
|
+
with:
|
|
74
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
75
|
+
files: ./coverage.xml
|
|
76
|
+
fail_ci_if_error: false
|
|
77
|
+
|
|
78
|
+
- name: Traceability mapping is up to date
|
|
79
|
+
run: |
|
|
80
|
+
if [ -d docs/internal ]; then
|
|
81
|
+
python tools/generate_requirements_mapping.py
|
|
82
|
+
git diff --exit-code docs/internal/requirements_to_tests_mapping.md
|
|
83
|
+
else
|
|
84
|
+
echo "Skipping traceability mapping (docs/internal not present in repo checkout)."
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
- name: CLI commands registry is valid
|
|
88
|
+
run: |
|
|
89
|
+
# Verify registry file exists and is valid JSON with expected structure
|
|
90
|
+
python -c "
|
|
91
|
+
import json
|
|
92
|
+
import sys
|
|
93
|
+
with open('mcp/.registry/commands.json') as f:
|
|
94
|
+
data = json.load(f)
|
|
95
|
+
assert 'commands' in data, 'Missing commands key'
|
|
96
|
+
assert isinstance(data['commands'], list), 'commands must be a list'
|
|
97
|
+
assert len(data['commands']) > 0, 'commands list is empty'
|
|
98
|
+
for cmd in data['commands']:
|
|
99
|
+
assert 'name' in cmd, f'Command missing name: {cmd}'
|
|
100
|
+
assert 'category' in cmd, f'Command {cmd[\"name\"]} missing category'
|
|
101
|
+
assert cmd['category'] in ('read', 'write', 'local'), f'Invalid category for {cmd[\"name\"]}'
|
|
102
|
+
print(f'Registry valid: {len(data[\"commands\"])} commands')
|
|
103
|
+
"
|
|
104
|
+
# 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
|
|
107
|
+
|
|
108
|
+
test-timezone:
|
|
109
|
+
runs-on: ubuntu-latest
|
|
110
|
+
strategy:
|
|
111
|
+
fail-fast: false
|
|
112
|
+
matrix:
|
|
113
|
+
tz: ["UTC", "America/New_York", "Europe/London", "Asia/Tokyo"]
|
|
114
|
+
|
|
115
|
+
steps:
|
|
116
|
+
- uses: actions/checkout@v6
|
|
117
|
+
|
|
118
|
+
- name: Set up Python
|
|
119
|
+
uses: actions/setup-python@v6
|
|
120
|
+
with:
|
|
121
|
+
python-version: "3.12"
|
|
122
|
+
cache: pip
|
|
123
|
+
cache-dependency-path: pyproject.toml
|
|
124
|
+
|
|
125
|
+
- name: Install
|
|
126
|
+
run: |
|
|
127
|
+
python -m pip install --upgrade pip
|
|
128
|
+
python -m pip install -e ".[dev]"
|
|
129
|
+
|
|
130
|
+
- name: Test with TZ=${{ matrix.tz }}
|
|
131
|
+
env:
|
|
132
|
+
TZ: ${{ matrix.tz }}
|
|
133
|
+
run: |
|
|
134
|
+
pytest tests/test_isodatetime.py -v
|
|
@@ -13,12 +13,12 @@ jobs:
|
|
|
13
13
|
build:
|
|
14
14
|
runs-on: ubuntu-latest
|
|
15
15
|
steps:
|
|
16
|
-
- uses: actions/checkout@
|
|
16
|
+
- uses: actions/checkout@v6
|
|
17
17
|
with:
|
|
18
18
|
fetch-depth: 0
|
|
19
19
|
|
|
20
20
|
- name: Set up Python
|
|
21
|
-
uses: actions/setup-python@
|
|
21
|
+
uses: actions/setup-python@v6
|
|
22
22
|
with:
|
|
23
23
|
python-version: "3.12"
|
|
24
24
|
cache: pip
|
|
@@ -54,14 +54,14 @@ jobs:
|
|
|
54
54
|
contents: write
|
|
55
55
|
concurrency:
|
|
56
56
|
group: docs-deploy
|
|
57
|
-
cancel-in-progress:
|
|
57
|
+
cancel-in-progress: false
|
|
58
58
|
steps:
|
|
59
|
-
- uses: actions/checkout@
|
|
59
|
+
- uses: actions/checkout@v6
|
|
60
60
|
with:
|
|
61
61
|
fetch-depth: 0
|
|
62
62
|
|
|
63
63
|
- name: Set up Python
|
|
64
|
-
uses: actions/setup-python@
|
|
64
|
+
uses: actions/setup-python@v6
|
|
65
65
|
with:
|
|
66
66
|
python-version: "3.12"
|
|
67
67
|
cache: pip
|
|
@@ -81,6 +81,10 @@ jobs:
|
|
|
81
81
|
git config user.name "github-actions[bot]"
|
|
82
82
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
83
83
|
|
|
84
|
+
- name: Fetch gh-pages branch
|
|
85
|
+
run: |
|
|
86
|
+
git fetch origin gh-pages:gh-pages || true
|
|
87
|
+
|
|
84
88
|
- name: Deploy (dev)
|
|
85
89
|
if: github.ref == 'refs/heads/main'
|
|
86
90
|
run: |
|
|
@@ -13,10 +13,10 @@ jobs:
|
|
|
13
13
|
runs-on: ubuntu-latest
|
|
14
14
|
timeout-minutes: 10
|
|
15
15
|
steps:
|
|
16
|
-
- uses: actions/checkout@
|
|
16
|
+
- uses: actions/checkout@v6
|
|
17
17
|
|
|
18
18
|
- name: Set up Python
|
|
19
|
-
uses: actions/setup-python@
|
|
19
|
+
uses: actions/setup-python@v6
|
|
20
20
|
with:
|
|
21
21
|
python-version: "3.12"
|
|
22
22
|
cache: pip
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
name: Build MCP Plugin
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- 'mcp/**'
|
|
8
|
+
- '!mcp/dist/**'
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
build:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v6
|
|
19
|
+
with:
|
|
20
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
21
|
+
|
|
22
|
+
- name: Install jq
|
|
23
|
+
run: sudo apt-get install -y jq
|
|
24
|
+
|
|
25
|
+
- name: Install mcp-bash framework
|
|
26
|
+
run: |
|
|
27
|
+
# Source version and commit from lockfile (single source of truth)
|
|
28
|
+
source mcp/mcp-bash.lock
|
|
29
|
+
echo "Installing mcp-bash v${MCPBASH_VERSION} (${MCPBASH_COMMIT})"
|
|
30
|
+
curl -fsSL https://raw.githubusercontent.com/yaniv-golan/mcp-bash-framework/main/install.sh | \
|
|
31
|
+
bash -s -- --version "v${MCPBASH_VERSION}" --yes
|
|
32
|
+
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
|
33
|
+
# Verify installed commit matches lockfile
|
|
34
|
+
INSTALLED_COMMIT=$(git -C "${XDG_DATA_HOME:-$HOME/.local/share}/mcp-bash" rev-parse HEAD)
|
|
35
|
+
if [[ "$INSTALLED_COMMIT" != "$MCPBASH_COMMIT" ]]; then
|
|
36
|
+
echo "::error::mcp-bash commit mismatch: expected $MCPBASH_COMMIT, got $INSTALLED_COMMIT"
|
|
37
|
+
exit 1
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
- name: Verify mcp-bash installation
|
|
41
|
+
run: |
|
|
42
|
+
mcp-bash --version
|
|
43
|
+
echo "mcp-bash installed successfully"
|
|
44
|
+
|
|
45
|
+
- name: Build MCP plugin ZIP
|
|
46
|
+
run: make -C mcp plugin
|
|
47
|
+
|
|
48
|
+
- name: Verify plugin structure
|
|
49
|
+
run: |
|
|
50
|
+
make -C mcp verify
|
|
51
|
+
test -f mcp/.claude-plugin/xaffinity-mcp.sh
|
|
52
|
+
test -f mcp/.claude-plugin/plugin.json
|
|
53
|
+
test -f mcp/.claude-plugin/xaffinity-mcp-plugin.zip
|
|
54
|
+
test -f mcp/.claude-plugin/VERSION
|
|
55
|
+
echo "Plugin structure validated"
|
|
56
|
+
|
|
57
|
+
- name: Test extraction
|
|
58
|
+
run: |
|
|
59
|
+
cd mcp/.claude-plugin
|
|
60
|
+
mkdir -p .mcp-extracted
|
|
61
|
+
unzip -q xaffinity-mcp-plugin.zip -d .mcp-extracted
|
|
62
|
+
test -x .mcp-extracted/xaffinity-mcp.sh
|
|
63
|
+
test -f .mcp-extracted/VERSION
|
|
64
|
+
rm -rf .mcp-extracted
|
|
65
|
+
echo "Extraction test passed"
|
|
66
|
+
|
|
67
|
+
- name: Validate MCPB configuration
|
|
68
|
+
run: |
|
|
69
|
+
cd mcp
|
|
70
|
+
mcp-bash bundle --validate
|
|
71
|
+
echo "MCPB configuration validated"
|
|
72
|
+
|
|
73
|
+
- name: Build MCPB bundle
|
|
74
|
+
run: |
|
|
75
|
+
cd mcp
|
|
76
|
+
mcp-bash bundle --output dist --verbose
|
|
77
|
+
ls -la dist/*.mcpb
|
|
78
|
+
echo "MCPB bundle created"
|
|
79
|
+
|
|
80
|
+
- name: Validate MCPB bundle structure
|
|
81
|
+
run: |
|
|
82
|
+
cd mcp
|
|
83
|
+
MCPB_FILE=$(ls dist/*.mcpb | head -1)
|
|
84
|
+
unzip -t "$MCPB_FILE"
|
|
85
|
+
unzip -p "$MCPB_FILE" manifest.json | jq .
|
|
86
|
+
echo "MCPB bundle structure validated"
|
|
87
|
+
|
|
88
|
+
- name: Test MCPB bundle health check
|
|
89
|
+
run: |
|
|
90
|
+
cd mcp
|
|
91
|
+
MCPB_FILE=$(ls dist/*.mcpb | head -1)
|
|
92
|
+
EXTRACT_DIR=$(mktemp -d)
|
|
93
|
+
unzip -q "$MCPB_FILE" -d "$EXTRACT_DIR"
|
|
94
|
+
# Test the wrapper script health check
|
|
95
|
+
"$EXTRACT_DIR/server/run-server.sh" --health || echo "Health check not available (expected if CLI not configured)"
|
|
96
|
+
rm -rf "$EXTRACT_DIR"
|
|
97
|
+
echo "MCPB bundle test completed"
|
|
98
|
+
|
|
99
|
+
- name: Upload plugin artifacts
|
|
100
|
+
uses: actions/upload-artifact@v6
|
|
101
|
+
with:
|
|
102
|
+
name: mcp-plugin
|
|
103
|
+
path: |
|
|
104
|
+
mcp/.claude-plugin/xaffinity-mcp-plugin.zip
|
|
105
|
+
mcp/dist/*.mcpb
|
|
106
|
+
retention-days: 30
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
name: Release MCP Plugin
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["mcp-v*.*.*"] # Renamed from plugin-v*
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
version:
|
|
9
|
+
description: "Version to release (without prefix, for API trigger)"
|
|
10
|
+
required: false
|
|
11
|
+
type: string
|
|
12
|
+
triggered_by:
|
|
13
|
+
description: "What triggered this release"
|
|
14
|
+
required: false
|
|
15
|
+
type: string
|
|
16
|
+
default: "manual"
|
|
17
|
+
tag:
|
|
18
|
+
description: 'Tag to release manually (e.g., mcp-v1.0.0, ignored if version set)'
|
|
19
|
+
required: false
|
|
20
|
+
|
|
21
|
+
permissions:
|
|
22
|
+
contents: write
|
|
23
|
+
|
|
24
|
+
jobs:
|
|
25
|
+
release:
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
steps:
|
|
28
|
+
- name: Determine version and tag
|
|
29
|
+
id: version
|
|
30
|
+
run: |
|
|
31
|
+
set -euo pipefail
|
|
32
|
+
if [[ -n "${{ inputs.version }}" ]]; then
|
|
33
|
+
# API-triggered release (from release-detect)
|
|
34
|
+
# Note: Version validation happens post-checkout in "Validate version matches VERSION file" step
|
|
35
|
+
echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT
|
|
36
|
+
echo "tag_name=mcp-v${{ inputs.version }}" >> $GITHUB_OUTPUT
|
|
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"
|
|
47
|
+
else
|
|
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
|
|
54
|
+
VERSION="${TAG_NAME#mcp-v}"
|
|
55
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
56
|
+
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
|
|
57
|
+
echo "is_api_trigger=false" >> $GITHUB_OUTPUT
|
|
58
|
+
echo "Mode: workflow_dispatch (manual), tag=$TAG_NAME, version=$VERSION"
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
- uses: actions/checkout@v6
|
|
62
|
+
with:
|
|
63
|
+
ref: ${{ steps.version.outputs.is_api_trigger == 'true' && 'main' || (github.event.inputs.tag || github.ref) }}
|
|
64
|
+
|
|
65
|
+
- name: Validate version matches VERSION file
|
|
66
|
+
run: |
|
|
67
|
+
set -euo pipefail
|
|
68
|
+
FILE_VERSION=$(cat mcp/VERSION | tr -d '[:space:]')
|
|
69
|
+
INPUT_VERSION="${{ steps.version.outputs.version }}"
|
|
70
|
+
if [[ "$FILE_VERSION" != "$INPUT_VERSION" ]]; then
|
|
71
|
+
echo "::error::Version mismatch: mcp/VERSION=$FILE_VERSION, expected=$INPUT_VERSION"
|
|
72
|
+
exit 1
|
|
73
|
+
fi
|
|
74
|
+
echo "Version validated: $FILE_VERSION"
|
|
75
|
+
|
|
76
|
+
- name: Install jq
|
|
77
|
+
run: sudo apt-get install -y jq
|
|
78
|
+
|
|
79
|
+
- name: Install mcp-bash framework
|
|
80
|
+
run: |
|
|
81
|
+
# Source version and commit from lockfile (single source of truth)
|
|
82
|
+
source mcp/mcp-bash.lock
|
|
83
|
+
echo "Installing mcp-bash v${MCPBASH_VERSION} (${MCPBASH_COMMIT})"
|
|
84
|
+
curl -fsSL https://raw.githubusercontent.com/yaniv-golan/mcp-bash-framework/main/install.sh | \
|
|
85
|
+
bash -s -- --version "v${MCPBASH_VERSION}" --yes
|
|
86
|
+
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
|
87
|
+
# Verify installed commit matches lockfile
|
|
88
|
+
INSTALLED_COMMIT=$(git -C "${XDG_DATA_HOME:-$HOME/.local/share}/mcp-bash" rev-parse HEAD)
|
|
89
|
+
if [[ "$INSTALLED_COMMIT" != "$MCPBASH_COMMIT" ]]; then
|
|
90
|
+
echo "::error::mcp-bash commit mismatch: expected $MCPBASH_COMMIT, got $INSTALLED_COMMIT"
|
|
91
|
+
exit 1
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
- name: Verify mcp-bash installation
|
|
95
|
+
run: mcp-bash --version
|
|
96
|
+
|
|
97
|
+
- name: Build Claude Code plugin ZIP
|
|
98
|
+
run: |
|
|
99
|
+
cd mcp
|
|
100
|
+
make plugin
|
|
101
|
+
echo "Plugin version: $(cat .claude-plugin/VERSION)"
|
|
102
|
+
ls -la .claude-plugin/xaffinity-mcp-plugin.zip
|
|
103
|
+
|
|
104
|
+
- name: Validate MCPB configuration
|
|
105
|
+
run: |
|
|
106
|
+
cd mcp
|
|
107
|
+
mcp-bash bundle --validate
|
|
108
|
+
|
|
109
|
+
- name: Build MCPB bundle
|
|
110
|
+
run: |
|
|
111
|
+
cd mcp
|
|
112
|
+
mcp-bash bundle --output dist --verbose
|
|
113
|
+
ls -la dist/*.mcpb
|
|
114
|
+
|
|
115
|
+
- name: Validate MCPB bundle structure
|
|
116
|
+
run: |
|
|
117
|
+
cd mcp
|
|
118
|
+
MCPB_FILE=$(ls dist/*.mcpb | head -1)
|
|
119
|
+
unzip -t "$MCPB_FILE"
|
|
120
|
+
unzip -p "$MCPB_FILE" manifest.json | jq .
|
|
121
|
+
echo "MCPB bundle validated"
|
|
122
|
+
|
|
123
|
+
- name: Test MCPB bundle health check
|
|
124
|
+
run: |
|
|
125
|
+
cd mcp
|
|
126
|
+
MCPB_FILE=$(ls dist/*.mcpb | head -1)
|
|
127
|
+
EXTRACT_DIR=$(mktemp -d)
|
|
128
|
+
unzip -q "$MCPB_FILE" -d "$EXTRACT_DIR"
|
|
129
|
+
"$EXTRACT_DIR/server/run-server.sh" --health || echo "Health check not available (expected if CLI not configured)"
|
|
130
|
+
rm -rf "$EXTRACT_DIR"
|
|
131
|
+
|
|
132
|
+
- name: Create and push tag (API trigger only)
|
|
133
|
+
if: steps.version.outputs.is_api_trigger == 'true'
|
|
134
|
+
run: |
|
|
135
|
+
git config user.name "github-actions[bot]"
|
|
136
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
137
|
+
git tag -a "${{ steps.version.outputs.tag_name }}" -m "Release ${{ steps.version.outputs.tag_name }}"
|
|
138
|
+
git push origin "${{ steps.version.outputs.tag_name }}"
|
|
139
|
+
|
|
140
|
+
- name: Create GitHub Release
|
|
141
|
+
uses: softprops/action-gh-release@v2
|
|
142
|
+
with:
|
|
143
|
+
tag_name: ${{ steps.version.outputs.tag_name }}
|
|
144
|
+
files: |
|
|
145
|
+
mcp/.claude-plugin/xaffinity-mcp-plugin.zip
|
|
146
|
+
mcp/dist/*.mcpb
|
|
147
|
+
generate_release_notes: true
|
|
148
|
+
name: MCP Server ${{ steps.version.outputs.tag_name }}
|
|
149
|
+
body: |
|
|
150
|
+
## Installation
|
|
151
|
+
|
|
152
|
+
### One-click install (Claude Desktop)
|
|
153
|
+
Download `xaffinity-mcp-*.mcpb` and double-click or drag to Claude Desktop.
|
|
154
|
+
|
|
155
|
+
### Claude Code
|
|
156
|
+
```bash
|
|
157
|
+
/plugin marketplace add yaniv-golan/affinity-sdk
|
|
158
|
+
/plugin install mcp@xaffinity
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Manual configuration
|
|
162
|
+
Download `xaffinity-mcp-plugin.zip` and configure your MCP client manually.
|
|
163
|
+
See [documentation](https://yaniv-golan.github.io/affinity-sdk/latest/mcp/) for details.
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
name: Release Detection
|
|
2
|
+
|
|
3
|
+
# Triggers releases automatically when version files change on main
|
|
4
|
+
# Only runs AFTER CI passes successfully
|
|
5
|
+
#
|
|
6
|
+
# Detection strategy: Compare current version against existing release tags.
|
|
7
|
+
# This is more robust than checking HEAD~1 because it works regardless of
|
|
8
|
+
# how many commits are pushed together, squash merges, rebases, etc.
|
|
9
|
+
|
|
10
|
+
on:
|
|
11
|
+
workflow_run:
|
|
12
|
+
workflows: ["CI"]
|
|
13
|
+
types: [completed]
|
|
14
|
+
branches: [main]
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
actions: write # Required for workflow_dispatch API
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
detect-changes:
|
|
22
|
+
# Only run if CI passed and it was a push (not PR)
|
|
23
|
+
if: >
|
|
24
|
+
github.event.workflow_run.conclusion == 'success' &&
|
|
25
|
+
github.event.workflow_run.event == 'push'
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
outputs:
|
|
28
|
+
sdk_changed: ${{ steps.changes.outputs.sdk }}
|
|
29
|
+
mcp_changed: ${{ steps.changes.outputs.mcp }}
|
|
30
|
+
sdk_version: ${{ steps.versions.outputs.sdk }}
|
|
31
|
+
mcp_version: ${{ steps.versions.outputs.mcp }}
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v6
|
|
34
|
+
with:
|
|
35
|
+
ref: ${{ github.event.workflow_run.head_sha }}
|
|
36
|
+
fetch-depth: 0 # Full history needed to check tags
|
|
37
|
+
|
|
38
|
+
- name: Extract versions
|
|
39
|
+
id: versions
|
|
40
|
+
run: |
|
|
41
|
+
set -euo pipefail
|
|
42
|
+
SDK_VERSION=$(grep '^version = ' pyproject.toml | head -1 | cut -d'"' -f2)
|
|
43
|
+
MCP_VERSION=$(cat mcp/VERSION | tr -d '[:space:]')
|
|
44
|
+
echo "sdk=$SDK_VERSION" >> $GITHUB_OUTPUT
|
|
45
|
+
echo "mcp=$MCP_VERSION" >> $GITHUB_OUTPUT
|
|
46
|
+
echo "SDK version in pyproject.toml: $SDK_VERSION"
|
|
47
|
+
echo "MCP version in mcp/VERSION: $MCP_VERSION"
|
|
48
|
+
|
|
49
|
+
- name: Detect unreleased versions
|
|
50
|
+
id: changes
|
|
51
|
+
run: |
|
|
52
|
+
set -euo pipefail
|
|
53
|
+
|
|
54
|
+
SDK_VERSION="${{ steps.versions.outputs.sdk }}"
|
|
55
|
+
MCP_VERSION="${{ steps.versions.outputs.mcp }}"
|
|
56
|
+
|
|
57
|
+
echo "Checking if releases exist for current versions..."
|
|
58
|
+
|
|
59
|
+
# Check if SDK version has a release tag
|
|
60
|
+
SDK_TAG="v${SDK_VERSION}"
|
|
61
|
+
if git tag -l "$SDK_TAG" | grep -q "^${SDK_TAG}$"; then
|
|
62
|
+
echo "SDK tag $SDK_TAG already exists - no release needed"
|
|
63
|
+
else
|
|
64
|
+
echo "SDK tag $SDK_TAG does not exist - release needed"
|
|
65
|
+
echo "sdk=true" >> $GITHUB_OUTPUT
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# Check if MCP version has a release tag
|
|
69
|
+
MCP_TAG="mcp-v${MCP_VERSION}"
|
|
70
|
+
if git tag -l "$MCP_TAG" | grep -q "^${MCP_TAG}$"; then
|
|
71
|
+
echo "MCP tag $MCP_TAG already exists - no release needed"
|
|
72
|
+
else
|
|
73
|
+
echo "MCP tag $MCP_TAG does not exist - release needed"
|
|
74
|
+
echo "mcp=true" >> $GITHUB_OUTPUT
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
trigger-sdk-release:
|
|
78
|
+
needs: detect-changes
|
|
79
|
+
if: needs.detect-changes.outputs.sdk_changed == 'true'
|
|
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
|
+
}
|
|
106
|
+
|
|
107
|
+
trigger-mcp-release:
|
|
108
|
+
needs: detect-changes
|
|
109
|
+
if: needs.detect-changes.outputs.mcp_changed == 'true'
|
|
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
|
+
}
|