Files

3.4 KiB

SharedInbox — Development Guide

Codeberg

We use Codeberg: https://codeberg.org/guettli/sharedinbox/

CLI tool fgj is available to query issues/PRs/actions.

Issue Label Workflow

Automation is handled by agentloop running every 5 minutes via cron. Add a label to trigger an agent:

Label Trigger Outcome
loop/plan Planning agent reads the issue and writes an implementation plan as a comment Issue moves to loop/plan-done
loop/code Coding agent implements the change, creates a branch + PR Issue routes to loop/merge
loop/merge Merge agent rebases, waits for CI, and merges the PR Issue moves to loop/merge-done

State machine:

loop/plan  →  loop/plan-in-process  →  loop/plan-done
                                     ↘  NeedSupervisor  (on failure)

loop/code  →  loop/code-in-process  →  loop/merge (via route)
                                     ↘  NeedSupervisor  (on failure)

loop/merge →  loop/merge-in-process →  loop/merge-done
                                     ↘  NeedSupervisor  (on failure)

Rules:

  • Only issues authored by allowed users are picked up (guettli, guettlibot, guettlibot2, forgejo-actions).
  • An issue with NeedSupervisor needs human attention — investigate, fix, then re-label.
  • The merge agent merges the PR automatically once CI is green. A human still reviews the PR before it merges if branch protection requires a review.
  • Planning agents only post a comment — they do NOT write code or open PRs.
  • loop/* labels are managed by agentloop — do not set them manually while an agent is active.

Typical lifecycle for a new feature:

1. Create issue
2. Add label loop/plan   → agent writes plan as comment
3. Review plan, request changes or approve
4. Add label loop/code   → agent implements + opens PR + hands off to merge
5. (Optional) Review PR before it merges
6. Merge agent waits for CI and merges the PR automatically

Code conventions

  • Avoid else, use "early return".

Drift (DB)

  • Schema in lib/data/db/database.dart.
  • After any schema change run: dart run build_runner build --delete-conflicting-outputs
  • Generated database.g.dart is committed — do not hand-edit it.

enough_mail

  • Standard pub dependency (enough_mail: ^2.1.7 in pubspec.yaml) — not vendored.
  • IMAP client helpers are in lib/data/imap/imap_client_factory.dart.

Running

Flutter build dependencies (libgtk-3-dev, libepoxy-dev, libsecret-1-dev, etc.) are installed via apt — see the Flutter Linux docs. The nix dev shell provides only tools: task, fvm, stalwart-mail.

Enter the nix dev shell first: nix develop

# Code generation (must run after schema changes)
task codegen

# Desktop
task run

# Tests
task test

Adding a screen

  1. Create lib/ui/screens/my_screen.dart.
  2. Add a GoRoute in lib/ui/router.dart.
  3. No separate ViewModel file needed — use ConsumerWidget / ConsumerStatefulWidget directly with Riverpod providers.

Continuous Integration (CI)

  • Strategy: "Thin CI, Heavy Taskfile".
  • Execution: CI must only invoke task commands (e.g., nix develop --command task check). All environment setup is handled by Nix (flake.nix), and all task orchestration is handled by Taskfile.yml.
  • The cli-tool fgj is available to query/wait for CI.