Skip to content

feat: integrations CLI + workflows step-delete#11

Open
chrisaddams wants to merge 1 commit into
mainfrom
feat/integrations
Open

feat: integrations CLI + workflows step-delete#11
chrisaddams wants to merge 1 commit into
mainfrom
feat/integrations

Conversation

@chrisaddams
Copy link
Copy Markdown
Contributor

Summary

Adds first-class integration management to the CLI plus a workflows step-delete command for cleaning up orphaned workflow steps.

Integrations

anythink integrations list
anythink integrations get <provider>
anythink integrations connections list [--provider <p>]

anythink integrations connect <provider>           # API-key (Claude, OpenAI, …)
anythink integrations oauth status <provider>
anythink integrations oauth configure <provider>
anythink integrations oauth callback-url          # dashboard URL to register with OAuth apps
anythink integrations oauth connect <provider>    # full browser OAuth dance via localhost:8745

anythink integrations test <connection-id>
anythink integrations enable <connection-id> | disable <id> | disconnect <id>
anythink integrations execute <provider> <op> --input k=v

Auth flows

  • API-key providers — prompts for the key (hidden) or accepts --api-key. Connection is created via POST /integrations/connections/api-key.
  • OAuth providersoauth configure stores tenant client credentials. oauth callback-url prints the dashboard's /settings/integrations/callback URL that users need to add to the OAuth app's redirect-URL allow list. oauth connect runs the full browser flow: binds a listener on localhost:8745, opens the browser, captures the code, posts to POST /integrations/connections. State validation prevents CSRF.

execute

Runs an operation on a connected provider:

anythink integrations execute claude generate-text --input "prompt=Tell me a haiku"
anythink integrations execute claude generate-text --inputs '{"prompt":"hi","model":"claude-3-haiku-20240307"}'

Outputs the response's content field by default; --json returns the full response.

workflows step-delete

anythink workflows step-delete <workflow_id> <step_id> [-y]

Detects inbound links before the delete. If the API rejects with a 500 (FK violation when another step's on_success_step_id/on_failure_step_id still references the target), the CLI translates the error into something actionable:

✗ Cannot delete step 84: still referenced by 1 other step(s).

Re-link or delete each of these first, then re-run:
  anythink workflows step-link 43 118 --on-success <NEW_TARGET>

Tests (19 new, 211 total — all passing)

  • tests/IntegrationsTests.cs — every integration client method, snake_case wire-format checks on POST/PUT bodies (we hit camelCase-vs-snake_case mismatches during dev), and IntegrationsCallbackUrl / DashboardUrl derivation.
  • tests/AnythinkClientExtendedTests.csDeleteWorkflowStepAsync happy path + 500 propagation.

Verified end-to-end against a live tenant

  • Configured Google + Slack OAuth credentials, surfaced the canonical dashboard callback URL via integrations oauth callback-url.
  • Ran oauth connect slack against the live API: localhost listener captured the code, POST to /integrations/connections created the connection, bot token stored.
  • Sent messages to a Slack channel via the Integration workflow action wired into a real workflow.
  • Used workflows step-delete to clean up 3 orphaned steps (get_user_badges_for_user, compute_new_badges, award_badges) on the workout_completed_points workflow. Verified the improved error translation by deliberately deleting a referenced step.

Notes / follow-ups (separate PRs)

  • The workflows trigger CLI has a payload-wrapping bug (wraps user JSON as { data: parsed } instead of building the proper TriggerWorkflowRequest). Not fixed in this PR — out of scope.
  • Event-typed workflows can't be triggered via the platform's manual trigger endpoint (server-side rejection). Worth lifting that constraint for testing, but server-side change.
  • API key client tests are in the feat/api-keys branch (feat: api-keys list/create/revoke commands #10), not duplicated here.

Integrations
------------
- integrations list / get <provider>: catalog browsing
- integrations connections list [--provider]: list active connections
- integrations connect <provider>: API-key connection (Claude, OpenAI, etc.).
  Prompts for the key (hidden) by default, accepts --api-key, supports
  --user-connection for user-scoped connections.
- integrations oauth status <provider>: shows OAuth client setup state
- integrations oauth configure <provider>: stores OAuth client_id + secret
  for a tenant. --use-social-sign-in flags it for social login.
- integrations oauth callback-url: prints the dashboard callback URL users
  need to add to their OAuth app's redirect URLs (the URL is also surfaced
  by oauth status / shown after a successful configure).
- integrations oauth connect <provider>: full browser OAuth dance — binds a
  local listener on http://localhost:8745/callback, opens the browser,
  captures the code, exchanges for a connection.
- integrations test <id> / enable <id> / disable <id> / disconnect <id>:
  connection lifecycle.
- integrations execute <provider> <operation>: runs an integration operation
  (e.g. claude generate-text). Inputs via repeated --input k=v or --inputs
  '<json>'. Output is the response's content field, or full JSON with --json.

Workflows
---------
- workflows step-delete <workflow_id> <step_id>: deletes a step. Detects
  inbound links and warns before the delete. If the API rejects with a 500
  (FK constraint when other steps still reference the target), translates
  the error into a clear message listing the offending steps and the
  step-link commands needed to fix them.

Tests
-----
- tests/IntegrationsTests.cs: 17 tests covering all integration client
  methods, snake_case wire format on POST/PUT bodies (the bug we hit during
  development), and IntegrationsCallbackUrl / DashboardUrl derivation.
- tests/AnythinkClientExtendedTests.cs: DeleteWorkflowStepAsync happy path
  plus 500 propagation for the FK-violation case.
- All 211 tests pass.

Verified end-to-end against staging:
- Slack OAuth dance: configure -> connect -> connection created with bot token
- Slack send-message via integrations execute (response received in channel)
- step-delete: deleted 3 orphans on workflow 36 (workout_completed_points)
  using the new command. Verified the FK-violation error translation by
  attempting to delete a step with inbound links.
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.

1 participant