-
Notifications
You must be signed in to change notification settings - Fork 9
feat(private-spaces): add private spaces endpoints, tools and organization field (ORB-1919) #74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
69ea8af
docs: add private spaces SDK design spec (ORB-1919)
JanKulhavy 900ded3
docs: add private spaces implementation plan (ORB-1919)
JanKulhavy 31a2291
feat(private-spaces): add PrivateSpaces endpoint with list() (ORB-1919)
JanKulhavy 57a6917
feat(private-spaces): add get() with usage columns (ORB-1919)
JanKulhavy a075f6f
feat(private-spaces): add update() with confirmed option (ORB-1919)
JanKulhavy 84d1572
feat(organizations): add privateSpaces column to Organization type (O…
JanKulhavy aea5e34
feat(private-spaces): export public types and document endpoint (ORB-…
JanKulhavy 5f01c44
feat(private-spaces): add tool definitions (ORB-1919)
JanKulhavy 45bc711
test(private-spaces): add integration tests (ORB-1919)
JanKulhavy bd8afd4
chore(private-spaces): formatting and verification follow-ups (ORB-1919)
JanKulhavy dd66ec8
test(private-spaces): skip restore when original limit was never obse…
JanKulhavy 6fe92c5
docs(private-spaces): correct nullable schema note in spec (ORB-1919)
JanKulhavy 598df55
fix(private-spaces): align transferLimit and consumedCenticredits typ…
JanKulhavy d67d809
feat: make JSONSchema type optional for enhanced flexibility
JanKulhavy b70f4f0
fix(private-spaces): resolve round-1 Copilot PR review comments
JanKulhavy e459b05
fix(private-spaces): checker findings — self-review round 1
JanKulhavy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| import type { Make } from '../make.js'; | ||
| import type { MakeTool } from '../tools.js'; | ||
|
|
||
| export const tools: MakeTool[] = [ | ||
| { | ||
| name: 'private-spaces_list', | ||
| title: 'List private spaces', | ||
| description: | ||
| "List the private spaces of an organization. Requires the organization's private-spaces feature to be enabled (error IM903 otherwise) and the 'personal team manage' permission. Private spaces cannot be created or deleted through the API — they are provisioned automatically by organization settings.", | ||
| category: 'private-spaces', | ||
| scope: 'private-spaces:read', | ||
| scopeId: 'organizationId', | ||
| identifier: 'organizationId', | ||
| annotations: { | ||
| readOnlyHint: true, | ||
| destructiveHint: false, | ||
| openWorldHint: false, | ||
| }, | ||
| inputSchema: { | ||
| type: 'object', | ||
| properties: { | ||
| organizationId: { type: 'number', description: 'The organization ID to list private spaces for' }, | ||
| externalId: { type: 'string', description: 'Filter private spaces by their external ID' }, | ||
| }, | ||
| required: ['organizationId'], | ||
| }, | ||
| examples: [{ organizationId: 5 }, { organizationId: 5, externalId: 'ext-1' }], | ||
| execute: async (make: Make, args: { organizationId: number; externalId?: string }) => { | ||
| const { organizationId, ...options } = args; | ||
| return await make.privateSpaces.list(organizationId, { ...options, cols: ['*'] }); | ||
| }, | ||
| }, | ||
| { | ||
| name: 'private-spaces_get', | ||
| title: 'Get private space', | ||
| description: | ||
| 'Get details of a specific private space, including usage totals (operations, transfer, centicredits). Callers who are not members of the space receive a 404 even when the space exists.', | ||
| category: 'private-spaces', | ||
| scope: 'private-spaces:read', | ||
| scopeId: 'privateSpaceId', | ||
| identifier: 'privateSpaceId', | ||
| resourceId: 'privateSpaceId', | ||
| annotations: { | ||
| readOnlyHint: true, | ||
| destructiveHint: false, | ||
| openWorldHint: false, | ||
| }, | ||
| inputSchema: { | ||
| type: 'object', | ||
| properties: { | ||
| privateSpaceId: { type: 'number', description: 'The private space ID to retrieve' }, | ||
| }, | ||
| required: ['privateSpaceId'], | ||
| }, | ||
| examples: [{ privateSpaceId: 101 }], | ||
| execute: async (make: Make, args: { privateSpaceId: number }) => { | ||
| return await make.privateSpaces.get(args.privateSpaceId, { cols: ['*'] }); | ||
| }, | ||
| }, | ||
| { | ||
| name: 'private-spaces_update', | ||
| title: 'Update private space', | ||
| description: | ||
| "Update a private space's operations limit. Set operationsLimit to null to remove the limit (unlimited); the transfer limit is derived automatically. When the new limit is below the space's current consumption the call fails with IM004 unless 'confirmed' is true — confirming pauses the space.", | ||
| category: 'private-spaces', | ||
| scope: 'private-spaces:write', | ||
| scopeId: 'privateSpaceId', | ||
| identifier: 'privateSpaceId', | ||
| resourceId: 'privateSpaceId', | ||
| annotations: { | ||
| readOnlyHint: false, | ||
| destructiveHint: true, | ||
| idempotentHint: true, | ||
| openWorldHint: false, | ||
| }, | ||
| inputSchema: { | ||
| type: 'object', | ||
| properties: { | ||
| privateSpaceId: { type: 'number', description: 'The private space ID to update' }, | ||
| operationsLimit: { | ||
| oneOf: [{ type: 'number' }, { type: 'null' }], | ||
| description: | ||
| 'Maximum operations limit (minimum 0). Pass null to remove the limit; omit to leave unchanged.', | ||
| }, | ||
| confirmed: { | ||
| type: 'boolean', | ||
| description: | ||
| "Confirmation of the update. Required when the new limit is below the space's current consumption; confirming pauses the space.", | ||
| }, | ||
| }, | ||
| required: ['privateSpaceId'], | ||
| }, | ||
| examples: [ | ||
| { privateSpaceId: 101, operationsLimit: 10000 }, | ||
| { privateSpaceId: 101, operationsLimit: 50, confirmed: true }, | ||
| { privateSpaceId: 101, operationsLimit: null }, | ||
| ], | ||
| execute: async ( | ||
| make: Make, | ||
| args: { privateSpaceId: number; operationsLimit?: number | null; confirmed?: boolean }, | ||
| ) => { | ||
| const { privateSpaceId, confirmed, ...body } = args; | ||
| return await make.privateSpaces.update(privateSpaceId, body, { confirmed }); | ||
| }, | ||
| }, | ||
| ]; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,230 @@ | ||
| import type { FetchFunction, Pagination, PickColumns } from '../types.js'; | ||
|
|
||
| /** | ||
| * Represents a private space in Make. | ||
| * A private space is a per-user personal workspace inside an organization where | ||
| * scenarios and related entities (including connections) stay visible only to the | ||
| * owner. Private spaces cannot be created or deleted through the API — they are | ||
| * provisioned automatically based on the organization's private-spaces settings. | ||
| */ | ||
| export type PrivateSpace = { | ||
| /** Unique identifier of the private space */ | ||
| id: number; | ||
| /** Name of the private space */ | ||
| name: string; | ||
| /** ID of the organization this private space belongs to */ | ||
| organizationId: number; | ||
| /** Whether Make global AI agents are enabled for the space */ | ||
| globalAgentsEnabled?: boolean; | ||
| /** Type of the underlying team; always `personal` for private spaces */ | ||
| type?: 'personal'; | ||
| /** Name of the space owner */ | ||
| privateSpaceOwnerName?: string; | ||
| /** Email of the space owner */ | ||
| privateSpaceOwnerEmail?: string; | ||
| /** User ID of the space owner */ | ||
| privateSpaceOwnerId?: number; | ||
| /** Maximum operations limit; null means unlimited */ | ||
| operationsLimit?: number | null; | ||
| /** | ||
| * Maximum data transfer limit in bytes; derived from the operations limit. | ||
| * Serialized as a string by `list()`/`get()` but as a number by `update()`. | ||
| */ | ||
| transferLimit?: string | number | null; | ||
| /** Number of operations consumed in the current period */ | ||
| consumedOperations?: number | null; | ||
| /** Amount of data transfer consumed in the current period, in bytes */ | ||
| consumedTransfer?: string | null; | ||
| /** Whether the space is paused due to exceeded limits */ | ||
| isPaused?: boolean | null; | ||
| /** Number of centicredits consumed in the current period, serialized as a string */ | ||
| consumedCenticredits?: string | null; | ||
| /** Total operations since the last reset; only selectable via `cols` on `get()` */ | ||
| operations?: string; | ||
| /** Total data transfer since the last reset, in bytes; only selectable via `cols` on `get()` */ | ||
| transfer?: string; | ||
| /** Total centicredits since the last reset; only selectable via `cols` on `get()` */ | ||
| centicredits?: string; | ||
| /** Whether the space is deleted; returned by `update()` */ | ||
| deleted?: boolean; | ||
| /** External identifier of the space; returned by `update()` */ | ||
| externalId?: string | null; | ||
| }; | ||
|
|
||
| /** | ||
| * Options for listing private spaces. | ||
| * @template C Keys of the PrivateSpace type to include in the response | ||
| */ | ||
| export type ListPrivateSpacesOptions<C extends keyof PrivateSpace = never> = { | ||
| /** Specific columns/fields to include in the response */ | ||
| cols?: C[] | ['*']; | ||
| /** Pagination options (the API supports sorting by `name` only) */ | ||
| pg?: Partial<Pagination<PrivateSpace>>; | ||
| /** Filter spaces by their external ID */ | ||
| externalId?: string; | ||
| }; | ||
|
|
||
| /** | ||
| * Options for retrieving a private space. | ||
| * @template C Keys of the PrivateSpace type to include in the response | ||
| */ | ||
| export type GetPrivateSpaceOptions<C extends keyof PrivateSpace = never> = { | ||
| /** | ||
| * Specific columns/fields to include in the response. In addition to the list | ||
| * columns, `get()` supports the usage totals `operations`, `transfer` and | ||
| * `centicredits` (computed from analytics storage; the API responds with 503 | ||
| * when that storage is unavailable). | ||
| */ | ||
| cols?: C[] | ['*']; | ||
| }; | ||
|
|
||
| /** | ||
| * Body for updating a private space. | ||
| */ | ||
| export type UpdatePrivateSpaceBody = { | ||
| /** | ||
| * Maximum operations limit (minimum 0). Set to `null` to remove the limit | ||
| * (unlimited); omit to leave unchanged. The transfer limit is derived from | ||
| * this value by the API. | ||
| */ | ||
| operationsLimit?: number | null; | ||
| }; | ||
|
|
||
| /** | ||
| * Options for updating a private space. | ||
| */ | ||
| export type UpdatePrivateSpaceOptions = { | ||
| /** | ||
| * Confirmation of the update. Required (the API fails with IM004 otherwise) | ||
| * when the new operations limit is below the space's current consumption; | ||
| * confirming pauses the space. | ||
| */ | ||
| confirmed?: boolean; | ||
| }; | ||
|
|
||
| /** | ||
| * Response format for listing private spaces. | ||
| */ | ||
| type ListPrivateSpacesResponse<C extends keyof PrivateSpace = never> = { | ||
| /** List of private spaces matching the query */ | ||
| privateSpaces: PickColumns<PrivateSpace, C>[]; | ||
| /** Pagination information */ | ||
| pg: Pagination<PrivateSpace>; | ||
| }; | ||
|
|
||
| /** | ||
| * Response format for getting a private space. | ||
| */ | ||
| type GetPrivateSpaceResponse<C extends keyof PrivateSpace = never> = { | ||
| /** The requested private space */ | ||
| privateSpace: PickColumns<PrivateSpace, C>; | ||
| }; | ||
|
|
||
| /** | ||
| * Response format for updating a private space. | ||
| */ | ||
| type UpdatePrivateSpaceResponse = { | ||
| /** The updated private space */ | ||
| privateSpace: PrivateSpace; | ||
| }; | ||
|
|
||
| /** | ||
| * Class providing methods for working with Make private spaces. | ||
| * Requires the organization's private-spaces feature to be enabled; the API | ||
| * responds with error IM903 when it is not. | ||
| */ | ||
| export class PrivateSpaces { | ||
| readonly #fetch: FetchFunction; | ||
|
|
||
| /** | ||
| * Create a new PrivateSpaces instance. | ||
| * @param fetch Function for making API requests | ||
| */ | ||
| constructor(fetch: FetchFunction) { | ||
| this.#fetch = fetch; | ||
| } | ||
|
|
||
| /** | ||
| * List private spaces of an organization. | ||
| * Requires the `personal team manage` organization permission. | ||
| * @param organizationId The organization ID to list private spaces for | ||
| * @param options Optional parameters for filtering and pagination | ||
| * @returns Promise with the list of private spaces | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const spaces = await make.privateSpaces.list(123); | ||
| * ``` | ||
| */ | ||
| async list<C extends keyof PrivateSpace = never>( | ||
| organizationId: number, | ||
| options?: ListPrivateSpacesOptions<C>, | ||
| ): Promise<PickColumns<PrivateSpace, C>[]> { | ||
| return ( | ||
| await this.#fetch<ListPrivateSpacesResponse<C>>('/private-spaces', { | ||
| query: { | ||
| organizationId, | ||
| externalId: options?.externalId, | ||
| cols: options?.cols, | ||
| pg: options?.pg, | ||
| }, | ||
| }) | ||
| ).privateSpaces; | ||
| } | ||
|
|
||
| /** | ||
| * Get details of a specific private space. | ||
| * Requires the `personal team own view` organization permission; callers who are | ||
| * not members of the space receive a 404 even when the space exists. | ||
| * @param privateSpaceId The private space ID to get | ||
| * @param options Optional parameters for filtering returned fields | ||
| * @returns Promise with the private space information | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const space = await make.privateSpaces.get(101); | ||
| * ``` | ||
| */ | ||
| async get<C extends keyof PrivateSpace = never>( | ||
| privateSpaceId: number, | ||
| options?: GetPrivateSpaceOptions<C>, | ||
| ): Promise<PickColumns<PrivateSpace, C>> { | ||
| return ( | ||
| await this.#fetch<GetPrivateSpaceResponse<C>>(`/private-spaces/${privateSpaceId}`, { | ||
| query: { | ||
| cols: options?.cols, | ||
| }, | ||
| }) | ||
| ).privateSpace; | ||
| } | ||
|
|
||
| /** | ||
| * Update a private space. | ||
| * Requires the `personal team manage` organization permission. | ||
| * @param privateSpaceId The private space ID to update | ||
| * @param body The fields to update | ||
| * @param options Optional update options | ||
| * @returns Promise with the updated private space | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Remove the operations limit | ||
| * const space = await make.privateSpaces.update(101, { operationsLimit: null }); | ||
| * ``` | ||
| */ | ||
| async update( | ||
| privateSpaceId: number, | ||
| body: UpdatePrivateSpaceBody, | ||
| options?: UpdatePrivateSpaceOptions, | ||
| ): Promise<PrivateSpace> { | ||
| return ( | ||
| await this.#fetch<UpdatePrivateSpaceResponse>(`/private-spaces/${privateSpaceId}`, { | ||
| method: 'PATCH', | ||
| query: { | ||
| confirmed: options?.confirmed, | ||
| }, | ||
| body, | ||
| }) | ||
| ).privateSpace; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.