Skip to content

Conversation

@miguelangaranocurrents
Copy link
Collaborator

Implemented 15 missing endpoints from the Currents REST API OpenAPI spec to achieve full parity:

Actions API (7 new endpoints):

  • GET /actions - List actions with filtering by status and search
  • POST /actions - Create new actions for skip/quarantine/tag operations
  • GET /actions/{actionId} - Get single action details
  • PUT /actions/{actionId} - Update existing actions
  • DELETE /actions/{actionId} - Archive actions (soft delete)
  • PUT /actions/{actionId}/enable - Enable disabled actions
  • PUT /actions/{actionId}/disable - Disable active actions

Projects API (2 new endpoints):

  • GET /projects/{projectId} - Get single project details
  • GET /projects/{projectId}/insights - Get aggregated run and test metrics

Runs API (5 new endpoints):

  • DELETE /runs/{runId} - Delete runs and associated data
  • GET /runs/find - Find runs by ciBuildId, branch, or tags
  • PUT /runs/{runId}/cancel - Cancel in-progress runs
  • PUT /runs/{runId}/reset - Reset failed specs for re-execution
  • PUT /runs/cancel-ci/github - Cancel runs by GitHub workflow ID

Improvements:

  • Added putApi() and deleteApi() helper methods to request.ts
  • Enhanced get-projects tool with pagination support (limit, starting_after, ending_before)
  • Added fetchAll parameter for automatic pagination
  • Updated all tool descriptions for better clarity
  • Fixed tests for get-projects to handle new parameters

OpenAPI Compliance:
All implementations match the OpenAPI spec v1.0.0 for:

  • Endpoint paths and HTTP methods
  • Request/response schemas
  • Query parameters and request bodies
  • Parameter types, constraints, and descriptions
  • Status codes and error handling

Closes: Full parity with OpenAPI spec at https://api.currents.dev/v1/docs/openapi.json

Implemented 15 missing endpoints from the Currents REST API OpenAPI spec to achieve full parity:

**Actions API (7 new endpoints):**
- GET /actions - List actions with filtering by status and search
- POST /actions - Create new actions for skip/quarantine/tag operations
- GET /actions/{actionId} - Get single action details
- PUT /actions/{actionId} - Update existing actions
- DELETE /actions/{actionId} - Archive actions (soft delete)
- PUT /actions/{actionId}/enable - Enable disabled actions
- PUT /actions/{actionId}/disable - Disable active actions

**Projects API (2 new endpoints):**
- GET /projects/{projectId} - Get single project details
- GET /projects/{projectId}/insights - Get aggregated run and test metrics

**Runs API (5 new endpoints):**
- DELETE /runs/{runId} - Delete runs and associated data
- GET /runs/find - Find runs by ciBuildId, branch, or tags
- PUT /runs/{runId}/cancel - Cancel in-progress runs
- PUT /runs/{runId}/reset - Reset failed specs for re-execution
- PUT /runs/cancel-ci/github - Cancel runs by GitHub workflow ID

**Improvements:**
- Added putApi() and deleteApi() helper methods to request.ts
- Enhanced get-projects tool with pagination support (limit, starting_after, ending_before)
- Added fetchAll parameter for automatic pagination
- Updated all tool descriptions for better clarity
- Fixed tests for get-projects to handle new parameters

**OpenAPI Compliance:**
All implementations match the OpenAPI spec v1.0.0 for:
- Endpoint paths and HTTP methods
- Request/response schemas
- Query parameters and request bodies
- Parameter types, constraints, and descriptions
- Status codes and error handling

Closes: Full parity with OpenAPI spec at https://api.currents.dev/v1/docs/openapi.json
@miguelangaranocurrents miguelangaranocurrents changed the title feat: add full OpenAPI parity with Actions and Runs management APIs [CSR-3565] feat: add full OpenAPI parity with Actions and Runs management APIs Jan 12, 2026
@notion-workspace
Copy link

@ynahmany ynahmany requested review from ynahmany and removed request for waltergalvao January 12, 2026 18:50
@ynahmany
Copy link
Contributor

@cubic-dev-ai please review.

@cubic-dev-ai
Copy link

cubic-dev-ai bot commented Jan 13, 2026

@cubic-dev-ai please review.

@ynahmany I have started the AI code review. It will take a few minutes to complete.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 19 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="mcp-server/src/tools/actions/update-action.ts">

<violation number="1" location="mcp-server/src/tools/actions/update-action.ts:66">
P2: Update endpoint allows empty body when no update fields are provided. Since all update fields (`name`, `description`, `action`, `matcher`, `expiresAfter`) are optional, a user can call this with only `actionId`, resulting in a PUT request with an empty body `{}`. Consider adding validation to ensure at least one update field is provided.</violation>
</file>

<file name="mcp-server/src/tools/projects/get-projects.ts">

<violation number="1" location="mcp-server/src/tools/projects/get-projects.ts:9">
P2: The `limit` field description states "max: 100" but no `.max(100)` constraint is applied to the zod schema. Users can pass values exceeding 100, bypassing the documented limit.</violation>
</file>

<file name="mcp-server/src/lib/request.ts">

<violation number="1" location="mcp-server/src/lib/request.ts:78">
P2: `deleteApi` unconditionally calls `response.json()` which will throw an error if the API returns 204 No Content (a common response for DELETE operations). This would cause successful deletions to be incorrectly reported as failures. Consider checking if the response has content before parsing JSON.</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Ask questions if you need clarification on any suggestion

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

cond: z.array(RuleMatcherCondition).min(1).describe("List of conditions to match"),
});

const zodSchema = z.object({
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Update endpoint allows empty body when no update fields are provided. Since all update fields (name, description, action, matcher, expiresAfter) are optional, a user can call this with only actionId, resulting in a PUT request with an empty body {}. Consider adding validation to ensure at least one update field is provided.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-server/src/tools/actions/update-action.ts, line 66:

<comment>Update endpoint allows empty body when no update fields are provided. Since all update fields (`name`, `description`, `action`, `matcher`, `expiresAfter`) are optional, a user can call this with only `actionId`, resulting in a PUT request with an empty body `{}`. Consider adding validation to ensure at least one update field is provided.</comment>

<file context>
@@ -0,0 +1,153 @@
+  cond: z.array(RuleMatcherCondition).min(1).describe("List of conditions to match"),
+});
+
+const zodSchema = z.object({
+  actionId: z.string().describe("The action ID to update."),
+  name: z
</file context>

limit: z
.number()
.optional()
.describe("Maximum number of items to return (default: 10, max: 100)."),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The limit field description states "max: 100" but no .max(100) constraint is applied to the zod schema. Users can pass values exceeding 100, bypassing the documented limit.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-server/src/tools/projects/get-projects.ts, line 9:

<comment>The `limit` field description states "max: 100" but no `.max(100)` constraint is applied to the zod schema. Users can pass values exceeding 100, bypassing the documented limit.</comment>

<file context>
@@ -1,10 +1,79 @@
+  limit: z
+    .number()
+    .optional()
+    .describe("Maximum number of items to return (default: 10, max: 100)."),
+  starting_after: z
+    .string()
</file context>
Suggested change
.describe("Maximum number of items to return (default: 10, max: 100)."),
.max(100)
.describe("Maximum number of items to return (default: 10, max: 100)."),

logger.error(response);
return null;
}
return (await response.json()) as T;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: deleteApi unconditionally calls response.json() which will throw an error if the API returns 204 No Content (a common response for DELETE operations). This would cause successful deletions to be incorrectly reported as failures. Consider checking if the response has content before parsing JSON.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mcp-server/src/lib/request.ts, line 78:

<comment>`deleteApi` unconditionally calls `response.json()` which will throw an error if the API returns 204 No Content (a common response for DELETE operations). This would cause successful deletions to be incorrectly reported as failures. Consider checking if the response has content before parsing JSON.</comment>

<file context>
@@ -56,6 +56,56 @@ export async function postApi<T, B>(path: string, body: B): Promise<T | null> {
+      logger.error(response);
+      return null;
+    }
+    return (await response.json()) as T;
+  } catch (error: any) {
+    logger.error("Error making Currents PUT request:", error.toString());
</file context>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants