Your stories, on your computer. Share with Git. Nothing else.
Website · Mac App Store · Linux AppImage · Snap Store · Windows Preview · ♥ Support · Issues · MIT License
FS User Stories is a local-first application for writing clear requirements without turning them into a project-management system. The native macOS app and the Qt app for Windows and Linux share the same Rust core and project format. It keeps the product deliberately small: projects, profiles, stories, acceptance criteria, one notes field, and attachments.
FS User Stories began with a practical need: a couple maintaining several projects together. One person writes code; the other understands the product, what should be built, and why. They often only need a clear, shared place to write down a feature so it can be implemented. The same shape appears in any small team where one person builds and another owns the product.
Tools such as Jira, Asana, and Trello can be excellent when their process is needed, but for this workflow they can add accounts, setup, ceremony, cost, and more surface area than the work requires. The same friction appears with many hosted MCP integrations: access can be paid or limited, the round trip can be slow, and large tool responses consume unnecessary agent context.
The stories stay on the computer, collaboration is optional through a repository the team already controls, and the local MCP server gives any compatible agent a small, direct interface to the same data.
There are no FS User Stories accounts, no telemetry, no required cloud, no subscriptions, no sprints, no estimates, no assignees, no deadlines, and no dashboards. The app works offline, exposes a local MCP server for compatible agents, and uses Git only when the user chooses to share a project.
FS User Stories does not manage your team, your dates, or your company. It only makes clear what needs to be built.
FS User Stories is a functional cross-platform product, not a static UI prototype. It includes a production macOS edition and Qt editions for Linux and Windows, all powered by the same Rust core and project format.
- SwiftUI interface designed around current macOS patterns and system materials.
- English and Spanish localization, selected from the user's system language.
- Large-window startup, standard keyboard commands, list navigation, contextual actions, and menu-bar access.
- A menu-bar companion that keeps projects and active stories accessible when the main window is closed, with a separate command to quit completely.
- Native confirmation dialogs for destructive operations.
- Search, collapsible Draft, Active, and Completed sections, status filtering, profile filtering, and newest/oldest/title ordering.
- A first-run choice to create a project, use an invitation, or connect an existing shared repository.
- Create and manage multiple local projects.
- Create, edit, search, and delete project profiles.
- Create, edit, duplicate, search, filter, and delete user stories.
- The focused user-story format: As a, I want, and So that.
- Exactly three states: Draft, Active, and Completed.
- Completed stories are read-only until they are reopened as Active or Draft.
- Checkable acceptance criteria with add, edit, and remove actions.
- Visual completion progress as completed criteria over total criteria.
- A direct Mark as Completed action once every criterion is satisfied.
- One intentionally simple notes field per story—no comment threads or activity feed.
- Export all, Active, Completed, Draft, or manually selected stories into one readable Markdown file; review and import selected stories from the same open format. Attachments are intentionally excluded from this transfer format.
- Add files with the file picker or drag and drop.
- Preview supported files with native macOS Quick Look.
- Files are copied into managed application storage, so moving the original does not break the story.
- Up to 10 attachments per story, 10 MB per file, and 50 MB total per story.
- Attachment metadata and SHA-256 hashes travel with the portable project data.
- Projects, profiles, stories, criteria, notes, and attachment metadata persist in a local SQLite database.
- Attachment contents remain in the app's managed Application Support directory.
- The application works fully without an Internet connection.
- UI and MCP operations use the same application layer and persistence rules, so data is not duplicated across separate implementations.
- Changes made through MCP notify the application and refresh the visible state.
The app runs a loopback-only MCP server while it is open. The MCP screen shows the live status, URL, port, and connection instructions; the same status is also visible in the app footer and menu bar.
Version 1.0.8 exposes 27 tools covering the product's real operations:
- Describe the application and list or inspect projects.
- Create projects and inspect repository status.
- List, create, edit, and delete profiles.
- Search and filter stories; read complete story details.
- Create, edit, duplicate, delete, and change the status of stories.
- Add, update, complete, and remove acceptance criteria.
- Update the single notes field.
- List, add, resolve, and delete managed attachments.
- Connect and synchronize shared repositories and create invitations.
Destructive MCP calls require explicit confirmation. Completed stories remain read-only through MCP just as they do in the UI. The server also includes a prompt that helps an agent inspect an existing codebase and propose profiles and user stories for the selected project.
The server binds only to the local loopback interface. FS User Stories operates no proxy, account service, or remote MCP infrastructure, and receives none of the user's project data.
Every project receives a private managed repository inside the app's Application Support directory. Users interact with simple product actions—connect, create, share, join, and synchronize—rather than with commits or branches.
- A remote is optional and may be hosted by GitHub, GitLab, or another compatible Git host.
- The app can connect an existing remote or create a private GitHub repository after browser-based Device Flow authorization.
- The GitHub OAuth token is stored in macOS Keychain when available. Development runs without Keychain entitlement keep it only in memory for that session. It is never written to SQLite, project JSON, invitations, logs, or Git.
- Repository owners can invite a GitHub collaborator by username from the app. A new Mac authorizes its own GitHub account automatically while joining a private GitHub project.
- SSH remotes use the user's existing local SSH agent. Public HTTPS remotes work without credentials.
- Share invitations contain the project identity and remote URL, never account credentials.
- Changes to separate stories or profiles merge automatically. Concurrent changes to the same item ask the user to choose Keep Mine or Use Shared.
- Every story has an immutable UUID identity. Human references such as
NUB-4remain readable labels; if two Macs create the same number concurrently, both stories survive and the duplicate references are renumbered deterministically. - Shared projects synchronize in the background with a visible per-project status. The active project refreshes more often, local edits use bounded debounce, and inactive projects are checked less frequently.
- The app never places the SQLite database in Git.
FS User Stories reserves the isolated fs-user-stories branch in every remote.
It never fetches, checks out, merges, pushes, force-pushes, or deletes main,
master, or another code branch. This keeps an existing source repository safe,
although a dedicated repository remains the clearest choice for a team.
- Linux x86_64 — direct download: FS User Stories 1.0.8 AppImage
- Linux x86_64 — store: Install from the Snap Store
- Windows x64 Preview: Download the 1.0.8 installer
- macOS Apple Silicon: Buy on the Mac App Store
The AppImage binary is hosted in the latest GitHub release. The Windows installer is an unsigned preview for collaborator testing while the Microsoft Store edition is prepared. Microsoft SmartScreen may show a warning.
Windows and Linux still need contributors. Linux 1.0.8 is now packaged and has passed clean Ubuntu 22.04 dependency, launch, core, and MCP checks. Windows is continuously compiled and smoke-tested, but we do not yet consider either Qt edition as mature as the native macOS edition. We welcome complete workflow testing, reproducible reports, and fixes through GitHub Issues.
Back up important project data and report unexpected behavior.
FS User Stories has passed its original Version 1 milestone. Version 1.0.8 is the current code release and includes the complete local-first workflow, Git sharing and automatic synchronization, portable attachments, and the local MCP server across the shared Rust core and platform interfaces.
- macOS: the production edition is distributed through the Mac App Store. It provides the complete native experience and is the reference edition.
- Windows x64: the Qt edition compiles in GitHub Actions, produces a single installer, and passes an automated installation smoke test. It is available for source builds and contributor testing, but is not yet considered ready for general distribution.
- Linux x64: version 1.0.8 is available from the Snap Store and as an AppImage. Both packages include the Qt runtime and Rust core and were tested on Magnolia; the AppImage was additionally verified on clean Ubuntu 22.04. Broader real-world testing is welcome.
The product promise is the same on every platform: local data, no FS User Stories account, no mandatory cloud, optional Git sharing, automatic repository repair and synchronization, portable attachments, and a local MCP server for the agent the user chooses. Windows and Linux contributors are welcome to help test complete workflows, improve packaging, and report reproducible issues.
- On the first Mac, open Share & Sync and choose Create on GitHub.
- Enter the second person's GitHub username under Invite a GitHub collaborator.
- The collaborator accepts GitHub's repository invitation.
- On the first Mac, choose Copy Invitation or Share Invitation….
- On the second Mac, choose Join Shared Project and paste the invitation.
- Authorize GitHub when the app opens Device Flow. No token is included in the invitation.
- Make a change on either Mac and watch the synchronization indicator. Use Synchronize Now only when an immediate manual refresh is useful.
SQLite is the local source of truth. Git synchronization exports an open, reviewable archive instead of copying the database:
.fs-user-stories/
├── project.json
├── README.md
├── profiles/
│ └── <profile-id>.json
├── stories/
│ └── <story-id>.json
└── attachments/
└── <story-id>/<managed-files>
The project header and one JSON file per profile and story form the synchronized source of truth. This keeps diffs focused, conflicts small, and the data directly readable by language models. A generated README summarizes the project for people. Attachments are copied, size-limited, and verified by hash.
The codebase separates the portable product core from the native macOS shell:
Sources/FSUserStoriesApp/App: application entry point and macOS lifecycle.Sources/FSUserStoriesApp/Application: observable UI state and command coordination through the Rust protocol.Sources/FSUserStoriesApp/Domain: Codable view models exchanged with Rust.Sources/FSUserStoriesApp/Infrastructure: thin macOS adapters for Keychain, security-scoped files, process execution, and system storage locations.Sources/FSUserStoriesApp/UI: SwiftUI views, components, localization, and native macOS presentation.Sources/FSUserStoriesApp/MCP: lifecycle adapter for the bundled Rust MCP process.Sources/FSUserStoriesApp/Infrastructure/Git: Rust command bridge, macOS background timers, and Keychain token storage.Core: authoritative Rust business rules, SQLite persistence, search, Markdown transfer, managed attachments, Git/GitHub synchronization, invitations, conflict handling, scheduling policy, and MCP server/tools.
The Rust core is compiled from the source under Core and bundled into each app
as a self-contained executable. There is one SQLite database and no alternate
platform backend. SwiftUI provides the native macOS interface, while Qt/QML
provides the Windows and Linux interfaces.
Source builds are available for macOS, Windows x64, and Linux x64. They do not need an Apple Developer account, GitHub token, or FS User Stories account. The Linux AppImage is attached to the v1.0.8 GitHub Release; Windows binaries remain limited to CI artifacts and collaborator testing, while macOS is distributed through the Mac App Store.
Requires macOS 26 or later, Xcode 26 or newer, Rust 1.97 or newer, CMake, and Git. After installing those tools, build with:
./Scripts/build-and-run-local.sh --no-openUse ./Scripts/build-and-run-local.sh --test to run the macOS and Rust tests.
On Ubuntu/Debian, install the build prerequisites once:
sudo apt install build-essential cmake ninja-build pkg-config git libsecret-1-dev
rustup toolchain install stableInstall a Qt 6.5 or newer desktop kit (Qt 6.7.3 gcc_64 is the tested kit).
Ubuntu 24.04's repository contains Qt 6.4, which is too old for this source.
When Qt is not in CMake's search path, point the build script to the kit:
export FS_USER_STORIES_QT_ROOT="$HOME/Qt/6.7.3/gcc_64"Then create a local AppImage with one command:
./Scripts/build-linux-app.shThe script builds the Rust core and Qt app. It requires linuxdeploy and its
Qt plugin only for the final AppImage wrapper; see docs/qt-build-linux.md for
their installation. For an unwrapped local executable, run
./Scripts/build-core-linux.sh, then CMake against Platform/Qt.
Install once: Visual Studio 2022 Build Tools with Desktop development with
C++, Rust, CMake, Ninja, NSIS, and Qt 6.7.3 msvc2019_64. Then, from PowerShell:
.\Scripts\build-windows-local.ps1If Qt is not in CMake's search path, set its kit directory first:
$env:FS_USER_STORIES_QT_ROOT = 'C:\Qt\6.7.3\msvc2019_64'
.\Scripts\build-windows-local.ps1This creates a local x64 installer under Distribution\Windows. Use
-SkipInstaller to compile only the app.
- Xcode 26 or newer.
- Rust 1.97 or newer.
- CMake, used only to compile the vendored libgit2 dependency.
- Git, for cloning the source and optional project synchronization.
Install Xcode from the Mac App Store, open it once to finish installing its components, and make it the active developer directory if necessary:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
xcodebuild -versionInstall Rust with the official rustup installer. Install CMake with Homebrew or another trusted package manager:
brew install cmake
rustc --version
cargo --version
cmake --versionClone the repository and run the local build helper:
git clone https://github.com/gitlares/fs-user-stories.git
cd fs-user-stories
./Scripts/build-and-run-local.shThe script validates the Mac and toolchain, compiles the Rust core from Core,
creates an unsigned local application and DMG under Distribution, and opens the
app. Use --no-open to build without launching or --test to run both suites:
./Scripts/build-and-run-local.sh --no-open
./Scripts/build-and-run-local.sh --testThe first build takes longer because Cargo compiles vendored libgit2 and OpenSSL from their locked source dependencies. Later builds reuse the local build cache. The resulting app is intended for use on the Mac that built it; share the official signed and notarized DMG with testers instead of redistributing this unsigned build.
No precompiled FS User Stories executable is stored in the repository. The
generated Rust core, Swift build products, application bundle, and DMG are all
ignored by Git. Core/Cargo.lock pins the complete Rust dependency graph so the
source used by Cargo can be reviewed and reproduced.
The application source, Rust core, build scripts, package metadata, OAuth client identifier, schemas, migrations, and dependency lockfile are public. The GitHub OAuth client identifier is intentionally included because Device Flow client IDs identify an application; they are not passwords or access tokens. Every user authorizes their own GitHub account, and credentials are never committed.
Official downloads add a Developer ID signature and an Apple notarization ticket to the application built by these scripts. The release owner's private signing key is the only release input that cannot be public. Anyone can independently build the unsigned application and inspect an official download with:
codesign --verify --deep --strict --verbose=2 "/Applications/FS User Stories.app"
spctl --assess --type execute --verbose=4 "/Applications/FS User Stories.app"Release notes publish a SHA-256 checksum for the DMG so testers can verify the
downloaded artifact with shasum -a 256.
Build the Rust core and then the macOS application:
./Scripts/build-core.sh
DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer swift buildRun the test suites:
DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer swift test
cargo test --manifest-path Core/Cargo.tomlCreate an unsigned local application and DMG:
./Scripts/package-release.shLocal data is stored in:
~/Library/Application Support/FS User Stories/
Removing the repository checkout does not remove that local application data. Do not delete the Application Support directory unless you intentionally want to remove every locally stored project and managed attachment.
Signing and notarization are release-owner actions performed separately with
Scripts/sign-and-notarize-release.sh. See
docs/releasing-macos.md for the release
checklist.
- No telemetry.
- No FS User Stories accounts.
- No FS User Stories servers.
- No subscriptions.
- No required cloud.
- No sprints, estimates, assignees, deadlines, or dashboards.
- No built-in AI provider.
- Local MCP for the tools the user chooses.
- Optional Git for sharing through infrastructure the user controls.
- Open and portable data.
- Dependencies compatible with commercial redistribution.
English is the default language for source code, documentation, issues, and pull requests. The application follows the user's system language and currently ships in English and Spanish.
FS User Stories is distributed under the MIT License. It permits
free and paid distributions, including a future commercial iOS edition. See
THIRD_PARTY_NOTICES.md for bundled dependency
licenses.
- FS Desktop LEDs — Control desk lighting from the Mac menu bar. Source code.
- FS PDF Compressor — Compress PDFs locally on macOS, Windows and Linux. Source code.
