feat: add the stacflow SDK and move flow_ui into a pub workspace - #45
Merged
Merged
Conversation
flow_ui moves unchanged to packages/flow_ui; the repo root becomes the pub workspace with melos scripts, and stacflow lives beside it as packages/stacflow so the two version in lockstep. The SDK re-exports flow_ui and adds Gemini, OpenAI and Claude adapters behind one transport seam, a client-side tool loop with read, write and destructive permissions, and the wire contract under contracts/ with its codegen. Provider call ids ride inside the tc_ tool-call ids, so tools land without a contract change.
…he local-mode launch The first release is stacflow without a gateway, so the contract folder becomes the SDK's own spec: the REST spec, the cloud-only error codes, the ui_payload event, the A2UI stub, the contracts lock and the mirror script into stacflow-cloud go. The stacflow docs-site pages come back with the site work later; the README carries the platform entries a host needs in the meantime.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit edfe1d3. Configure here.
…odegen The generator was 594 lines producing 456, against a schema this package is the only consumer of. contracts/ stays as the specification; sse_events.dart and error_codes.dart move next to the rest of the transport layer and are maintained by hand, which also puts them under very_good_analysis for the first time.
withSupportedImages had no label to pass: wire_history.dart knew the attachment's name but WireImagePart did not carry it, so a HEIC on Claude or a GIF on Gemini reached the model as "Attachment file" instead of its name.
…shable Five review findings on this branch. finish() closed the controller without marking the emitter done, so stopping a turn mid-request threw twice. retry() spliced a failed turn out of the middle, leaving a history that ended with an assistant turn. editAndResend truncated the thread before discovering it had nothing to send. The pana gate never stubbed the example's gitignored key file, unlike ci.yml. And the examples' `resolution: workspace` shipped inside the published archives, where no workspace root exists to resolve it.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.

Summary
Turns the repo into a Dart pub workspace and adds the StacFlow SDK beside flow_ui.
packages/flow_uiis the published package, moved as-is. Every file underlib/is a pure rename; no widget changes.packages/stacflowis the SDK:StacFlowChat, the controller, andStacFlowChatView, the ready-made screen on flow_ui. Gemini, OpenAI and Claude adapters run natively with the developer's own key behind oneTurnTransportseam, with streaming, stop, retry, regenerate, edit and resend, image attachments, copy, feedback and a model selector. The key is a private field set on exactly one header and never appears in URLs, logs or errors.Toolwithread,writeanddestructivepermissions, a confirmation card for gated calls,runToolLoop(dispatch, approval, timeouts, abort, continuation segments, a rounds cap), and the tool card in the thread withtoolBodyBuilderfor custom result bodies. Calls and results replay to the model in later turns on all three providers; Claude thinking blocks and Gemini signatures replay within a turn. Provider call ids ride inside thetc_ids, socontracts/is unchanged by tools.contracts/holds the wire contract (SSE events, error codes) withtool/contracts_gen.dartgeneratingpackages/stacflow/lib/src/generatedand CI failing on drift.set_themetool, andCLAUDE.md/AGENTS.mdfor the workspace conventions.pubspec.yamlcarries the melos scripts;playgroundandpackages/stacflowdepend onflow_ui: ^0.4.0.Releases stay per package:
flow_ui-v*andstacflow-v*tags. stacflow keepspublish_to: noneuntil the 0.1.0 tag; the version bump is a follow-up.Screenshots
Nothing in flow_ui renders differently; every
lib/file is a pure move. The SDK's view composes existing flow_ui components (thread, composer, tool and confirmation cards).How this was verified
dart run melos run analyzeclean in all five members;dart format --set-exit-if-changed .clean.packages/stacflow/tool/smoke.dart) against Claude withTOOLS=true, includingTOOL_PERMISSION=destructiveandDECLINE=true.set_themetool).Checklist
dart run melos run analyzeis cleandart run melos run formatapplieddependencies:inpackages/flow_ui/pubspec.yamlis flutter.dev-published, forces no configuration on hosts that never use the feature, and is argued in this PR (none added)packages/stacflow, enforced by the CI greppackages/flow_ui/lib/flow_ui.dartand documented indocs/and the README table (no new flow_ui API; stacflow's API is exported fromlib/stacflow.dartand documented in its README; the docs site pages come later)packages/flow_ui/CHANGELOG.mdupdated for user-facing changes, with breaking changes called out (no flow_ui changes in this PR; the stacflow CHANGELOG carries 0.1.0)feat:,fix:,refactor:,docs:,chore:)Note
High Risk
Large monorepo and release-process change plus a new SDK that handles API keys, provider HTTP, streaming, and client tool execution—areas that are security- and behavior-sensitive even though flow_ui widgets are largely unchanged.
Overview
Restructures the repository into a Dart pub workspace (root
pubspec.yaml+ melos for analyze/format/test) and moves the published UI library topackages/flow_uiat 0.4.0, with per-package.pubignore, a slim root README, and docs/playground paths updated accordingly.Adds
packages/stacflow, the StacFlow SDK:StacFlowChat/StacFlowChatViewon flow_ui, Gemini/OpenAI/Claude providers, streaming turn transport, client tools (permissions, confirmations, tool loop), plus a runnable example app andcontracts/wire specs (SSE events and error codes) aligned with hand-maintained transport types.CI and release shift to workspace-wide checks, a boundaries job (flow_ui must not depend on stacflow), app matrix builds for flow_ui example, stacflow example, and playground, and per-package release tags (
flow_ui-v*,stacflow-v*) driving pana, pub publish, and docs deploy. Example apps switch API keys to--dart-define/ gitignored env files instead of committed stubs where applicable.Reviewed by Cursor Bugbot for commit e15020f. Bugbot is set up for automated code reviews on this repo. Configure here.