Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/hub/code.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Integration ids look like `int_…`.

## Marketplace

The 24 routes of the gateway contract `Code.Marketplace.md` §14: the catalog
The 28 routes of the gateway contract `Code.Marketplace.md` §14: the catalog
of listings, the installed connections (integration ids look like `int_…`),
their secrets and token mappings, and the functions added on a connection
(`func_…`). Every method, its verb, path, query and body are asserted in
Expand All @@ -56,6 +56,10 @@ their secrets and token mappings, and the functions added on a connection
| `get_marketplace_listing` | `GET` | `/{version}/code/marketplace/listings/{ListingViewId}` | `project` | path: `listing_view_id` |
| `test_marketplace_integration` | `POST` | `/{version}/code/marketplace/integrations/{IntegrationViewId}/test` | `project` | path: `integration_view_id` |
| `get_marketplace_integration_tools` | `GET` | `/{version}/code/marketplace/integrations/{IntegrationViewId}/tools` | `project` | path: `integration_view_id`; returns the stored MCP tool catalog (`tools`, `listedAt`, `catalogHash`, `truncated`) |
| `get_marketplace_integration_access` | `GET` | `/{version}/code/marketplace/integrations/{IntegrationViewId}/access` | `project` | path: `integration_view_id`; returns the access matrix (`roles`, `packages`, `tools`, `functions`) |
| `set_marketplace_integration_role_access` | `PUT` | `/{version}/code/marketplace/integrations/{IntegrationViewId}/access/roles` | `project` | path: `integration_view_id`; JSON body: `roleId`, `package` (`None`, `Viewer`, `FunctionsOnly`, `ReadOnly`, `FullAccess`), `manage`; returns the role id |
| `save_marketplace_integration_custom_access` | `POST` | `/{version}/code/marketplace/integrations/{IntegrationViewId}/access/roles/custom` | `project` | path: `integration_view_id`; JSON body: `roleId`, `basePackage`, `tools`, `functions`, `manage`, `newPolicyForThisRoleOnly`; returns `policyId`, `created`, `usedByRoles` |
| `start_marketplace_integration_sign_in` | `POST` | `/{version}/code/marketplace/integrations/{IntegrationViewId}/oauth/start` | `project` | path: `integration_view_id`; returns `authorizeUrl` (open it in a browser), `redirectUrl`, `expiresAt` |
| `replace_marketplace_integration_secrets` | `PUT` | `/{version}/code/marketplace/integrations/{IntegrationViewId}/secrets` | `project` | path: `integration_view_id`; JSON body: `secrets` |
| `reveal_marketplace_integration_secrets` | `POST` | `/{version}/code/marketplace/integrations/{IntegrationViewId}/secrets/reveal` | `project` | path: `integration_view_id` |
| `set_marketplace_integration_token_mappings` | `PUT` | `/{version}/code/marketplace/integrations/{IntegrationViewId}/token-mappings` | `project` | path: `integration_view_id`; JSON body: `tokenMappings` |
Expand Down
209 changes: 208 additions & 1 deletion references/hub_dtos.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
""" Options:
Date: 2026-10-13 09:01:23
Date: 2026-10-13 13:23:39
Version: 10.20
Tip: To override a DTO option, remove "#" prefix before updating
BaseUrl: http://localhost:5001
Expand Down Expand Up @@ -2797,6 +2797,7 @@ class MarketplaceValidationStepResultDto:
succeeded: bool = False
skipped: bool = False
message: Optional[str] = None
error_code: Optional[str] = None


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
Expand All @@ -2809,6 +2810,10 @@ class MarketplaceIntegrationDto(IntegrationDto):
description: Optional[str] = None
config: Optional[IReadOnlyDictionary[str, str]] = None
last_validation_steps: Optional[List[MarketplaceValidationStepResultDto]] = None
signed_in: bool = False
signed_in_by: Optional[str] = None
signed_in_at: Optional[datetime.datetime] = None
token_expires_at: Optional[datetime.datetime] = None


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
Expand Down Expand Up @@ -2954,6 +2959,8 @@ class MarketplaceListingDto(IHasViewId):
documentation_url: Optional[str] = None
video_url: Optional[str] = None
availability: Optional[MarketplaceAvailability] = None
connect_steps: Optional[IReadOnlyList[str]] = None
o_auth_redirect_url: Optional[str] = None
is_official: bool = False
tags: Optional[IReadOnlyList[str]] = None
spec_version: int = 0
Expand Down Expand Up @@ -3951,6 +3958,15 @@ class SmsIntegrationRequest:
is_enabled: bool = False


class MarketplaceAccessLevel(str, Enum):
NONE = 'None'
VIEWER = 'Viewer'
FUNCTIONS_ONLY = 'FunctionsOnly'
READ_ONLY = 'ReadOnly'
FULL_ACCESS = 'FullAccess'
MANAGE = 'Manage'


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class SavePushTemplate(CodeMashRequestBase):
Expand Down Expand Up @@ -5928,6 +5944,54 @@ class MarketplaceListingProjection(IHasViewId):
video_url: Optional[str] = None


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class MarketplaceAccessCustomPolicyDto:
policy_id: Optional[str] = None
name: Optional[str] = None
used_by_roles: int = 0


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class MarketplaceAccessRoleDto:
role_id: Optional[str] = None
name: Optional[str] = None
scope: Optional[str] = None
is_system: bool = False
fixed: bool = False
package: Optional[MarketplaceAccessLevel] = None
is_custom: bool = False
manage: bool = False
custom: Optional[IReadOnlyList[MarketplaceAccessCustomPolicyDto]] = None
default_not_applied: Optional[str] = None


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class MarketplaceAccessPackageDto:
kind: Optional[MarketplaceAccessLevel] = None
policy_id: Optional[str] = None
name: Optional[str] = None
exists: bool = False


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class MarketplaceAccessToolDto:
name: Optional[str] = None
read_only: bool = False
grantable: bool = False


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class MarketplaceAccessFunctionDto:
function_id: Optional[str] = None
name: Optional[str] = None
function_key: Optional[str] = None


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class MarketplaceIntegrationListProjection(IHasViewId):
Expand All @@ -5943,6 +6007,8 @@ class MarketplaceIntegrationListProjection(IHasViewId):
last_integration_test_errors: Optional[IReadOnlyList[str]] = None
human_delivery_confirmed_at_utc: Optional[datetime.datetime] = None
requires_human_delivery_confirmation: bool = False
signed_in: bool = False
signed_in_at: Optional[datetime.datetime] = None


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
Expand All @@ -5956,6 +6022,14 @@ class MarketplaceMcpToolDto:
destructive_hint: Optional[bool] = None


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class MarketplaceAccessChangesDto:
read_only_added: Optional[IReadOnlyList[str]] = None
read_only_removed: Optional[IReadOnlyList[str]] = None
not_grantable: Optional[IReadOnlyList[str]] = None


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class MarketplaceFunctionProjection(IHasViewId):
Expand Down Expand Up @@ -8050,6 +8124,23 @@ class GetMarketplaceListingsResponse(ResponseBase):
list: Optional[PaginatedResponse[MarketplaceListingProjection]] = None


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class GetMarketplaceIntegrationAccessResponse(ResponseBase):
roles: Optional[IReadOnlyList[MarketplaceAccessRoleDto]] = None
packages: Optional[IReadOnlyList[MarketplaceAccessPackageDto]] = None
tools: Optional[IReadOnlyList[MarketplaceAccessToolDto]] = None
functions: Optional[IReadOnlyList[MarketplaceAccessFunctionDto]] = None


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class SaveMarketplaceIntegrationCustomAccessResponse(ResponseBase):
policy_id: Optional[str] = None
created: bool = False
used_by_roles: int = 0


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class GetMarketplaceIntegrationResponse(ResponseBase):
Expand All @@ -8071,6 +8162,14 @@ class GetMarketplaceIntegrationToolsResponse(ResponseBase):
truncated: bool = False


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class StartMarketplaceIntegrationSignInResponse(ResponseBase):
authorize_url: Optional[str] = None
redirect_url: Optional[str] = None
expires_at: Optional[datetime.datetime] = None


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class EmptyMarketplaceSecretsResponse(ResponseBase):
Expand All @@ -8088,6 +8187,7 @@ class RevealMarketplaceIntegrationSecretsResponse(ResponseBase):
class TestMarketplaceIntegrationResponse(ResponseBase):
items: Optional[IReadOnlyList[IntegrationTestResultItemDto]] = None
steps: Optional[IReadOnlyList[MarketplaceValidationStepResultDto]] = None
access_changes: Optional[MarketplaceAccessChangesDto] = None


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
Expand Down Expand Up @@ -15332,6 +15432,102 @@ class GetSmsCampaignMessagesRequest(CodeMashListPaginationRequestBase, IReturn[G
"""


# @Route("/{version}/code/marketplace/integrations/{IntegrationViewId}/access", "GET")
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class GetMarketplaceIntegrationAccess(CodeMashRequestBase, IReturn[GetMarketplaceIntegrationAccessResponse]):
# @ApiMember(Description="Integration view id, from get_marketplace_integrations.", IsRequired=true)
integration_view_id: Optional[str] = None
"""
Integration view id, from get_marketplace_integrations.
"""


# @Route("/{version}/code/marketplace/integrations/{IntegrationViewId}/access/roles", "PUT")
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class SetMarketplaceIntegrationRoleAccess(CodeMashRequestBase, IReturn[IdResponse]):
# @ApiMember(Description="Integration view id, from get_marketplace_integrations.", IsRequired=true)
integration_view_id: Optional[str] = None
"""
Integration view id, from get_marketplace_integrations.
"""


# @ApiMember(Description="The role's composite id: acc_…_nr_… (account / team role) or pr_…_nr_… (project role).", IsRequired=true)
role_id: Optional[str] = None
"""
The role's composite id: acc_…_nr_… (account / team role) or pr_…_nr_… (project role).
"""


# @ApiMember(Description="None, Viewer, FunctionsOnly, ReadOnly or FullAccess.")
package: Optional[MarketplaceAccessLevel] = None
"""
None, Viewer, FunctionsOnly, ReadOnly or FullAccess.
"""


# @ApiMember(Description="True to also give the Manage package (edit the connection, its secrets, validation and functions).")
manage: bool = False
"""
True to also give the Manage package (edit the connection, its secrets, validation and functions).
"""


# @Route("/{version}/code/marketplace/integrations/{IntegrationViewId}/access/roles/custom", "POST")
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class SaveMarketplaceIntegrationCustomAccess(CodeMashRequestBase, IReturn[SaveMarketplaceIntegrationCustomAccessResponse]):
# @ApiMember(Description="Integration view id, from get_marketplace_integrations.", IsRequired=true)
integration_view_id: Optional[str] = None
"""
Integration view id, from get_marketplace_integrations.
"""


# @ApiMember(Description="The role's composite id: acc_…_nr_… or pr_…_nr_….", IsRequired=true)
role_id: Optional[str] = None
"""
The role's composite id: acc_…_nr_… or pr_…_nr_….
"""


# @ApiMember(Description="The package to start from: None, Viewer, FunctionsOnly, ReadOnly or FullAccess.")
base_package: Optional[MarketplaceAccessLevel] = None
"""
The package to start from: None, Viewer, FunctionsOnly, ReadOnly or FullAccess.
"""


# @ApiMember(Description="Tool names the role may run (from the connection's tools).")
tools: List[str] = field(default_factory=list)
"""
Tool names the role may run (from the connection's tools).
"""


# @ApiMember(Description="Function ids (func_…) of this connection the role may run.")
functions: List[str] = field(default_factory=list)
"""
Function ids (func_…) of this connection the role may run.
"""


# @ApiMember(Description="True to include the Manage rights (edit the connection, its secrets, validation and functions).")
manage: bool = False
"""
True to include the Manage rights (edit the connection, its secrets, validation and functions).
"""


# @ApiMember(Description="True to write a new policy for this role only when its current custom policy is shared with other roles.")
new_policy_for_this_role_only: bool = False
"""
True to write a new policy for this role only when its current custom policy is shared with other roles.
"""


# @Route("/{version}/code/marketplace/integrations/{IntegrationViewId}/tools", "GET")
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
Expand All @@ -15343,6 +15539,17 @@ class GetMarketplaceIntegrationTools(CodeMashRequestBase, IReturn[GetMarketplace
"""


# @Route("/{version}/code/marketplace/integrations/{IntegrationViewId}/oauth/start", "POST")
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
class StartMarketplaceIntegrationSignIn(CodeMashRequestBase, IReturn[StartMarketplaceIntegrationSignInResponse]):
# @ApiMember(Description="Integration view id, from get_marketplace_integrations.", IsRequired=true)
integration_view_id: Optional[str] = None
"""
Integration view id, from get_marketplace_integrations.
"""


# @Route("/{version}/code/marketplace/integrations/{IntegrationViewId}/secrets", "PUT")
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)
@dataclass
Expand Down
Loading
Loading