feat(sdk,cli): flow requirements and integration connect prompts on deploy/schedule/run --cloud
Why
Deploying examples/stale-issues (header tools: { slack: true }, body f.slack.post) to Cloud succeeds today and fails on the first run with helper_slack.credential_missing: neither flows deploy, flows schedule nor flows run --cloud asks whether the workspace has Slack connected, and the deploy wizard's required set is GitHub + ticket sources only. agentworkforce deploy already solves this for proactive agents with the relayfile connect-session prompt; this PR gives flows the same behaviour.
What
flowRequirements(definition | compiled spec, { sources, repository, projectCli }) (packages/sdk/src/flow-requirements.ts) → { integrations: [{ provider, from: 'tools'|'source'|'helper', detail }], harnesses, harnessUses, mcp }, from inert declarations only:
| Requirement | Read from |
|---|---|
slack (tools.slack) | tools.<helper>: true header flag |
notion (tools.relayfile) | first segment of each tools.relayfile mount |
linear (f.linear) | body use without a flag — the same root.<namespace> / root["namespace"] recognition preflightHelpers uses, so what preflight would refuse for a missing mount is what this names |
github (on github issues) | provider triggers via providerDeclaration (.on(github.issues())) |
github (--on github) / github (deploy target) | the --on sources; every deployment run lands in --repo |
claude (agent "review"), codex (llm step), claude (step "b") | cli: on each f.agent/f.llm call (basename-matched to claude/codex/gemini), else nearest flows.json cli, else Cloud's default claude; compiled specs use step → named agent → flow cli |
mcp fs (tools.mcp) | tools.mcp |
flows check prints REQUIRES slack (tools.slack), github (deploy target), claude (agent "review") and carries requirements in --json.
Connect before submit (packages/sdk/src/cloud-connect.ts, cli/cloud-connect-cli.ts): before flows deploy, flows schedule and flows run --cloud submit, each required integration is checked with GET /api/v1/workspaces/<id>/integrations/<provider>/status?scope=workspace (list fallback on 404; unknown_provider is named, not treated as disconnected). A missing one prompts:
This flow needs Slack (tools.slack), which is not connected to this workspace.
Connect Slack now? (opens browser) [Y/n]
Opening https://…/connect
Slack connected.
Yes → POST …/integrations/connect-session { allowedIntegrations: ["slack"], scope: { kind: "workspace" } } → connectLink (also sessionUrl/url) opened detached in the browser (FLOWS_NO_BROWSER=1 prints only) → status polled every 2s for up to 5 minutes. --no-connect, --json, no TTY, or an answer of no refuse with integration_not_connected (exit 2) naming the provider, the declaration and both remedies. --draft skips the check, as Cloud does. A flow that requires nothing contacts nothing extra.
flows deploy now defaults --agents to the harnesses the source declares, sends requirements in the deploy body (Cloud ignores unknown fields today; AgentWorkforce/cloud#3788 reads it), prints requires:/connected: lines, and appends Connect it with: agent-relay cloud connect <harness> to flow_model_not_connected / cli_credentials_missing refusals — there is no status route for harness credentials, so the refusal is where the remedy is named.
Tests
tests/flow-requirements.test.ts— derivation on in-process definitions, a compiled spec, and the shippedstale-issues,software-factory,pr-review-pipelineexamples;flows checkoutput and--json.tests/cloud-connect.test.ts— status/list/unknown-provider reads; prompt accept/decline/timeout/refused session; connect-session body and browser opening;cliConnectPromptTTY/--json/--no-connectrules and answer parsing;harnessRemedy;flows deploy/run --cloud/schedulerefusing before any submit,run --cloudsubmitting after a prompted connect,--draftskipping,--jsonrefusing.tests/cloud-deploy.test.ts,tests/cli.test.tsupdated for the new calls/fields.
Not verified live: a real browser connect against production (the mocked contract mirrors workforce/packages/deploy/src/connect.ts and cloud's connect-session / [provider]/status routes).
🤖 Generated with Claude Code
[!NOTE]
Medium Risk
Changes pre-submit behavior and Cloud API calls for all hosted CLI paths; failures are mostly early refusals, but interactive connect and new deploy fields need correct workspace/auth handling in CI and production.
Overview
Adds flowRequirements so the SDK can infer integrations, coding-agent harnesses, and MCP needs from static flow declarations (headers, default body, triggers, deploy context). flows check now prints a REQUIRES … line and exposes requirements in --json.
Before flows deploy, flows schedule, or flows run --cloud submit, the CLI checks workspace integration status and can prompt to connect via Cloud’s connect-session flow (browser + poll). --no-connect, --json, non-TTY, or --draft deploy skip or refuse instead of prompting; missing integrations exit 2 with integration_not_connected.
flows deploy defaults --agents from declared cli: harnesses, sends requirements in the deploy payload, prints requires: / connected:, and appends agent-relay cloud connect <harness> on harness credential refusals. Unsupported declared harnesses (e.g. gemini) are refused unless --agents overrides.
Reviewed by Cursor Bugbot for commit 123d0e22dfadce21c65ac38c25bc50c6708a4baa. Bugbot is set up for automated code reviews on this repo. Configure here.
Agent Relay sessions
claudesessionaa342204· opened viagh pr create· last active 2026-09-18