feat: add Flutter client SDK and demo app - #463
Draft
fforootd wants to merge 9 commits into
Draft
Conversation
Adds docs/design/sdk-flutter/PLAN.md describing how a Flutter client SDK fits the nextgen architecture: a pure-Dart zitadel_client (handwritten flow/session client with spec-lock tests against the OpenAPI spec) plus a zitadel_flutter widget package natively rendering the BDUI flow contract, a demo app, Moon/CI wiring, and an independent pub.dev release path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012xLyz1YWAuFY8GK1scWaNF
First milestone of the Flutter SDK plan (docs/design/sdk-flutter/PLAN.md): a dependency-free Dart package driving the BDUI flow API (create/submit/ current with the 400-with-step unwrap), the session API (handoff exchange, me, revoke with bearer session_token), _zflow cookie capture/replay, and en/de/it locale dictionaries ported from @zitadel/components. Models are hand-written against api/openapi with a spec-lock test suite that fails when the spec and models drift. Contract tests drive a live apps/mock-zitadel through the full login journey including the handoff exchange. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012xLyz1YWAuFY8GK1scWaNF
Second milestone of the Flutter SDK plan: ZitadelLogin renders server-driven steps natively (ordered fields/actions from the capability arrays, localized labels, validation hints, error banners), driven by a FlowController that ports the <zitadel-login> orchestrator state machine (value seeding and carry-over, current-step-only submits, rotated flow handles, double-submit guard, optional automatic handoff exchange). Includes ZitadelSession/ZitadelLogout, an isolate-based altcha proof-of-work solver, secure keychain-backed token/cookie stores, a pub-conventional example app, and controller/widget/solver test suites. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012xLyz1YWAuFY8GK1scWaNF
Third milestone of the Flutter SDK plan: Home (ZitadelSession card + sign-out when signed in), full-screen ZitadelLogin with automatic handoff exchange, and a Settings screen persisting base URL/project id via shared_preferences. README documents the three run modes (mock-zitadel, npx @zitadel/cli start, deployed /__nextgen proxy). AGENTS.md package map now covers the Dart packages and their out-of-changesets release path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012xLyz1YWAuFY8GK1scWaNF
…rkflow Adds subosito/flutter-action to the full-pr CI job so the sdk-dart/ sdk-flutter/demo-flutter moon tasks (system commands) find dart/flutter on PATH, converts their compound moon tasks to script form, links the sdk-flutter example app to the in-repo packages via pubspec_overrides, and adds release-flutter.yml: a manual, OIDC-authenticated pub.dev publish (dry-run by default) that tests both packages, enforces version lockstep, publishes zitadel_client, waits for it to resolve on pub.dev, then publishes zitadel_flutter without the path overrides. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012xLyz1YWAuFY8GK1scWaNF
The Dart packages have no package.json, so Changesets and the release manifest already ignore them mechanically (verified via check-changesets-status.mjs); this makes the human-facing logic match: .changeset/README.md documents the pub.dev exception, AGENTS.md states the Moon-vs-Changesets ownership exception plus the release procedure (lockstep pubspec bumps, hand-maintained changelogs, release-flutter dispatch), CONTRIBUTING.md points contributors at the Flutter toolchain and Moon targets, and release-publish.yml excludes the Dart package paths from its npm-publish triggers so Dart CHANGELOG merges don't fire the changesets train. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012xLyz1YWAuFY8GK1scWaNF
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
|
fforootd
added a commit
that referenced
this pull request
Jul 6, 2026
## Summary - Add a direct Moon dependency from `cli:build-release` to `cli:test` so the production-stamped CLI build cannot clean and rewrite `apps/cli/dist` while Vitest is exercising oclif command discovery from that same directory. - Keep the CLI Vitest global setup self-contained by asserting that the tsdown-built command files exist and `oclif commands --json` discovers `status` before any test files run. - Remove the runtime 127 retry from the in-process CLI test helper so the test harness fails fast instead of masking a graph/order problem. ## Validation - `moon run cli:build-release` (runs `cli:test` before the production CLI build; captured log shows `cli:test` 101 files / 672 tests passed and `cli:build-release` completed) - `moon run cli:typecheck` - `moon run cli:lint` - `node scripts/check-changesets-status.mjs --base origin/main --summary` - `corepack pnpm exec changeset status --since origin/main` - `git diff --check origin/main...HEAD` ## Release notes / changeset Empty changeset added: `.changeset/cli-build-release-dag.md`. This changes package-local Moon build wiring under `@zitadel/cli`, but no shipped CLI behavior changes and no package bump is planned. ## Notes - The broader problem is the Moon graph/shared-output ordering, not the PATH-sensitive server lifecycle prober. - Blame points to the interaction between the original CLI Vitest global setup from `0547b8c3` / #319 and the release build DAG from `b0ba758a` / #418, which introduced `cli:build-release` as a CI-visible production build that cleans the same `apps/cli/dist` directory. - Live open-PR check: PR #463 reproduced the `status` exit-127 class with `cli:build`, `cli:test`, and `cli:build-release` all building CLI dist in the same full-pr graph. PR #462 and the older filtered failed logs did not show this oclif/status signature.
…-sdk-plan-y4ao9i # Conflicts: # .changeset/README.md
…proof opt-in Two review findings on #463: Formatting: CI's lint ran dart format without a resolved package config, so the formatter fell back to the latest language version while local runs (post pub get) pinned the package's SDK floor — different styles, red lint. Bump the Dart floor to ^3.8.0, reformat everything in the matching style, and make the lint tasks run pub get first so the style is always pinned by the package config regardless of SDK version. Gate proofs: the server currently rejects any non-empty gate_proofs as reserved (internal/domain/flow_state_machine.go) and never emits gates. Solving altcha gates is now behind FlowController/ZitadelLogin enableAltchaGates (default off); by default altcha gates surface via onUnsupportedCapability like every other provider and no proofs go on the wire. README and plan doc updated to match; solver + tests stay. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012xLyz1YWAuFY8GK1scWaNF
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
Introduces the Dart/Flutter SDK for Zitadel NextGen authentication, consisting of:
packages/sdk-dart(zitadel_client): Pure-Dart client for the flow and session APIs. ProvidesFlowClient(create/submit/current flow steps),SessionClient(handoff token exchange), and cookie/token storage abstractions. Hand-written thin client with spec-lock tests to prevent API drift.packages/sdk-flutter(zitadel_flutter): Flutter widgets built on the Dart client.ZitadelLoginnatively renders server-driven flow steps (BDUI) with Material widgets and localized labels. IncludesZitadelSession/ZitadelLogoutwidgets and secure token storage viaflutter_secure_storage.apps/demo-flutter: Reference Flutter app demonstrating the SDK in three modes (mock server, local Zitadel, deployed proxy). Configurable via settings UI.The implementation mirrors the web SDK architecture: server-driven flows, native rendering, automatic cookie replay, and optional session auto-exchange. Localization covers English, German, and Italian. Includes altcha proof-of-work solver for CAPTCHA gates.
Validation
FlowClient,SessionClient,FlowController, andZitadelLoginwidgetRelease notes / changeset
No changeset required — these are new packages (
zitadel_clientv0.1.0-alpha.1,zitadel_flutterv0.1.0-alpha.1) published independently to pub.dev outside the npm lockstep train. Manual dispatch workflow added for future releases.Notes
docs/design/sdk-flutter/PLAN.mdpubspec_overrides.yamlenables monorepo development linkingdemo-flutterproject.gitignoreand CI workflows updated for Dart/Flutter toolchainhttps://claude.ai/code/session_012xLyz1YWAuFY8GK1scWaNF