Skip to content

feat: add connection create and update commands - #221

Open
qbalin wants to merge 3 commits into
mainfrom
devin/ent-6443-connection-create-update
Open

feat: add connection create and update commands#221
qbalin wants to merge 3 commits into
mainfrom
devin/ent-6443-connection-create-update

Conversation

@qbalin

@qbalin qbalin commented Aug 14, 2026

Copy link
Copy Markdown

Summary

Adds workos connection create and workos connection update <id> for provisioning and migrating SSO connections via the Connections API, plus a connections alias for the resource (kept out of metric fragmentation via command-aliases.ts).

  • Body assembly: --data '<json>' and --file <path|-> (stdin) provide the raw request body; top-level flags --org/--organization-id, --name, --external-id, --type override/merge on top. Nested saml_options / oidc_options / attribute_maps are passed through the raw JSON body. Non-object JSON bodies are rejected with invalid_json_body (type-narrowed via an isJsonObject guard — no casts).
  • workos-api.ts: add PATCH to WorkOSRequestOptions['method'] and send JSON bodies for PATCH.
  • workos-client.ts: new connections.create(body) / connections.update(id, body) raw methods.
  • connection create requires organization_id; connection update rejects an empty body. Both support human and --json output and reuse the standard API-key resolution and error handling.

These endpoints are feature-gated server-side (connections-api-migrations-capabilities-api) and return 404 unless enabled for the team.

Part of https://linear.app/workos/issue/ENT-6443 — companion docs PR in workos/workos.

Test plan

  • bun run typecheck, bun run lint, bun run format:check, bun run build — clean.
  • bun run vitest run src/commands/connection.spec.ts src/lib/workos-api.spec.ts — new specs cover request construction, flag/JSON precedence, --file/stdin parsing, invalid JSON, empty update body, API errors, and JSON output mode.

Link to Devin session: https://app.devin.ai/sessions/9151860048f44f5084cd0fe314e8722c
Requested by: @qbalin

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@qbalin qbalin self-assigned this Aug 14, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor
Original prompt from quentin.balin

Pick up this ticket. Ask any questions if need be: https://linear.app/workos/issue/ENT-6443/docs-cli-integration-workos-connections-create-update

@linear-code

linear-code Bot commented Aug 14, 2026

Copy link
Copy Markdown

ENT-6443

@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@greptile-apps

greptile-apps Bot commented Aug 14, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds CLI commands for creating and updating SSO connections through the Connections API.

  • Registers connection create and connection update, with raw JSON/file input and top-level flag overrides.
  • Extends the API transport and client with PATCH-backed connection updates.
  • Adds the connections alias, static JSON help entries, documentation, and command/client tests.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/commands/connection.ts Adds request-body parsing, validation, and handlers for connection creation and updates.
src/lib/workos-api.ts Extends the shared API transport to accept PATCH and serialize PATCH request bodies.
src/lib/workos-client.ts Adds raw Connections API methods for creating and updating SSO connections.
src/bin.ts Registers the new subcommands and the plural connection alias.
src/utils/help-json.ts Mirrors the new connection commands in the static machine-readable help catalog.

Sequence Diagram

sequenceDiagram
  participant User
  participant CLI as connection command
  participant Client as workos-client
  participant Transport as workosRequest
  participant API as WorkOS Connections API
  User->>CLI: create/update flags or JSON
  CLI->>CLI: parse and merge request body
  CLI->>Client: connections.create/update
  Client->>Transport: POST/PATCH request options
  Transport->>API: authenticated JSON request
  API-->>Transport: connection response
  Transport-->>CLI: parsed connection
  CLI-->>User: human or JSON output
Loading

Reviews (3): Last reviewed commit: "fix: use success envelope for connection..." | Re-trigger Greptile

greptile-apps[bot]

This comment was marked as resolved.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 2 potential issues.

Open in Devin Review

Comment thread src/commands/connection.ts Outdated
Comment on lines +177 to +181
outputJson(connection);
return;
}
outputSuccess('Created connection', connection);
} catch (error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Machine-readable output for creating and updating connections omits the standard success wrapper

The newly created/updated connection is printed as a bare object (outputJson(connection) at src/commands/connection.ts:177-181) instead of the standard success envelope every other create/update command emits, so scripts and agents that read the status field get nothing back.
Impact: Automated callers parsing JSON output of these two commands see a different shape than for all other resource create/update commands and can mis-handle the result.

Why this deviates from the established output convention

CLAUDE.md requires new resource commands to follow the patterns in src/commands/organization.ts. There, create/update call outputSuccess('Created organization', org) (src/commands/organization.ts:34, src/commands/organization.ts:56), which in JSON mode produces { status: 'ok', message, data } (src/utils/output.ts:66-85). The same convention is used by role.ts (src/commands/role.ts:87, src/commands/role.ts:116) and by runConnectionDelete in this very file (src/commands/connection.ts:257). The new runConnectionCreate/runConnectionUpdate instead short-circuit with isJsonMode() + raw outputJson, matching only the get convention. Removing the isJsonMode() branch and calling outputSuccess alone yields both human and JSON output consistently (the new specs at src/commands/connection.spec.ts:288-302 would need to read output.data).

Suggested change
outputJson(connection);
return;
}
outputSuccess('Created connection', connection);
} catch (error) {
outputSuccess('Created connection', connection);
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Fixed in 588ce9b — create/update now call outputSuccess(...) unconditionally, so JSON mode emits the standard { status: 'ok', message, data } envelope like the other resource create/update commands, and the specs assert on output.status/output.data.

Comment thread src/lib/workos-client.ts
Comment on lines +203 to +221
connections: {
async create(body: Record<string, unknown>) {
return workosRequest<SsoConnection>({
method: 'POST',
path: '/connections',
apiKey: key,
baseUrl: base,
body,
});
},
async update(id: string, body: Record<string, unknown>) {
return workosRequest<SsoConnection>({
method: 'PATCH',
path: `/connections/${encodeURIComponent(id)}`,
apiKey: key,
baseUrl: base,
body,
});
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔍 create/update return snake_case while get returns camelCase

connections.create/connections.update use the raw fetch wrapper and therefore return the API's snake_case shape (SsoConnection at src/lib/workos-client.ts:30-41), whereas runConnectionGet and runConnectionList return SDK-mapped camelCase objects (src/commands/connection.ts:220, src/commands/connection.ts:48-56). Consumers of --json output will see connection_type/organization_id from create/update but type/organizationId from get/list on the same resource. Worth confirming this is acceptable for agent tooling, or normalizing the raw response before printing.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Accurate observation. This is deliberate: the pinned @workos-inc/node (8.13.0) has no createConnection/updateConnection, so these go through the raw transport, and I kept the API's snake_case shape in the output rather than hand-rolling a camelCase mapping. It's also symmetric with the input — --data/--file bodies are authored in the API's snake_case shape (matching the API reference docs), so the response echoes the same field names. If the SDK later ships these methods, switching to it would align create/update with get/list automatically. Happy to normalize now instead if consistency across subcommands matters more for agent tooling.

@qbalin
qbalin requested a review from jonatascastro12 August 14, 2026 17:55
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant