This is the operating guide for agents working in the API Dash repository. Treat it as a working contract, not a static note. If you change behavior, architecture, commands, generated models, storage, package boundaries, or test strategy, update this file and architecture.md in the same change.
Scope note: this guide describes the main branch architecture. If you are on a feature branch, verify whether the feature is merged before documenting it here. Do not describe branch-only work as mainline behavior.
- Preserve user work. Check
git status --shortbefore edits and do not revert unrelated modified or untracked files. - Read before changing. Inspect the touched source, nearby tests, root docs, and relevant developer docs before implementing.
- Prefer the existing architecture. API Dash is a Flutter/Melos monorepo using Riverpod, Hive, Freezed/json_serializable, Jinja templates, and modular packages. Do not introduce another state, storage, routing, networking, or codegen pattern unless the task explicitly requires it.
- Keep root docs current. Working agents must update
AGENTS.mdandarchitecture.mdwhenever their changes alter how future agents should understand, test, or extend the system. - Keep mainline docs honest. GSoC proposals, local branch files, and unmerged experiments are useful references, but they are not source-of-truth architecture for these root docs.
- Generated Dart files are build outputs. Edit source model files, then run generation. Do not manually patch
.freezed.dartor.g.dartas the primary fix. - Tests should be focused and offline by default. Use in-memory mocks and provider overrides unless the production component specifically requires a scoped loopback server, such as OAuth callback handling.
The current main branch supports:
| Area | Mainline status |
|---|---|
| HTTP/REST requests | Supported |
| GraphQL requests | Supported through HTTP POST body construction |
| SSE and streaming HTTP responses | Supported through streaming MIME detection |
| AI requests | Supported through genai and better_networking |
| WebSocket requests | Supported |
| Dashbot assistant | Supported |
| cURL, Postman, Insomnia, HAR import | Supported |
| OpenAPI-assisted import | Supported through Dashbot services |
| Code generation | Supported for cURL, HAR, C, C#, Dart, Go, JS, Java, Julia, Kotlin, PHP, Python, Ruby, Rust, Swift |
| Environment Variables | Supported |
| Request History | Supported |
| Path | Responsibility |
|---|---|
lib/main.dart |
Startup: Stac init, model discovery, settings load, Hive init, desktop window init, provider overrides |
lib/app.dart |
App shell, theme, workspace selector, desktop/mobile routing, close/save behavior |
lib/consts.dart |
App constants, feature labels, codegen language enum, import format enum, response view routing |
lib/models/ |
App-level Freezed models: request, history, settings |
lib/providers/ |
Riverpod state for requests, environments, history, settings, UI, terminal, JS runtime |
lib/services/ |
Hive, shared preferences, history retention, window services, agentic helper calls |
lib/screens/ |
Feature pages and responsive desktop/mobile page composition |
lib/widgets/ |
Reusable app widgets and response preview widgets |
lib/codegen/ |
Request-to-code generation router and language implementations |
lib/importer/ |
Import dialog and facade over cURL/Postman/Insomnia/HAR parsers |
lib/dashbot/ |
Dashbot UI, chat state, prompts, actions, OpenAPI/cURL apply flows |
lib/terminal/ |
Terminal/log data models and terminal widgets |
packages/ |
Workspace packages shared by the app |
test/ |
Root app unit and widget tests |
integration_test/ |
Desktop/mobile integration tests |
doc/dev_guide/ |
Contributor-facing setup, testing, architecture, and extension guides |
doc/proposals/ |
Proposal material; not implementation source of truth |
API Dash uses a Melos workspace with the root app plus 12 packages.
| Package | Responsibility |
|---|---|
packages/seed |
Shared low-level models such as NameValueModel and FormDataModel |
packages/better_networking |
HTTP/GraphQL/SSE execution, auth, request/response models, cancellation, OAuth callback server |
packages/genai |
Unified AI request model, provider adapters, model manager, agentic engine |
packages/apidash_core |
Import/export adapters, environment model, shared core utilities |
packages/apidash_design_system |
Design tokens, typography, themes, context extensions, base widgets |
packages/curl_parser |
cURL parsing and Dart-to-cURL conversion helpers |
packages/postman |
Postman collection models and parsing utilities |
packages/insomnia_collection |
Insomnia export models and parsing utilities |
packages/har |
HAR 1.2 models and utilities |
packages/json_explorer |
Interactive JSON explorer widget |
packages/json_field_editor |
JSON editing, validation, and highlighting widget |
packages/multi_trigger_autocomplete_plus |
Multi-trigger autocomplete used for variable entry patterns |
Run commands from the repository root unless noted.
Setup:
dart pub global activate melos
melos bootstrap
melos pub-get
flutter pub getFormat and Analyze:
dart format .
melos analyzeRoot app tests:
flutter test --coverage
flutter test test/path/to_test.dartWorkspace package tests:
melos test
melos exec --scope=<package_name> -- flutter testCode generation:
melos build-gen
dart run build_runner build --delete-conflicting-outputsRun locally:
flutter run
flutter run -d linux
flutter run -d macos
flutter run -d windowsCoverage HTML, when lcov is installed:
genhtml coverage/lcov.info -o coverage/htmlStart every task with this sequence:
- Check the active branch and worktree.
- Identify whether the user wants current branch behavior or
mainbranch behavior. - Read the current docs and the source files around the target behavior.
- Find existing tests for the same layer before adding new test patterns.
- Make the narrowest code/doc change that solves the request.
- Run the smallest meaningful verification first; broaden when the blast radius is shared or architectural.
- Update
AGENTS.mdandarchitecture.mdif the change affects agent guidance or architecture. - Report what changed and which verification ran.
Use main as a reference when requested:
git show main:path/to/file.dart
git ls-tree -r --name-only main
git grep -n "pattern" main -- lib packages testWhen creating branches or opening pull requests on behalf of the user, follow these project conventions based on CONTRIBUTING.md:
- Branch Naming: Use
add-feature-<name>,resolve-issue-<name>, oradd-test-<name>. - PR Scope: Prefer precise changes (e.g., adding a single test or resolving one issue) over massive PRs with many unrelated file changes.
- PR Description: Include a clear title and description, and reference the corresponding issue (e.g.,
#issue-number). - AI Policy: Mention in the PR description if the contribution is AI-assisted, especially for large or complex changes.
Root docs must stay concise enough to guide future work. They should describe current mainline architecture, commands, decisions that affect many files, and rules agents must follow.
Detailed implementation diaries are allowed, but keep them separate from the root docs:
- Use local task notes for line-by-line reasoning, rejected approaches, subagent findings, temporary hypotheses, command transcripts, and detailed decision trails.
- Prefer a task-scoped path such as
doc/agent_notes/<topic>.mdor another user-specified local note path. - Mark local notes with branch, date, author/agent, scope, and whether the notes are mainline, branch-only, or scratch.
- Do not cite local notes as source-of-truth architecture unless their content has been promoted into
architecture.mdor relevant developer docs. - Do not put every line-level change in
architecture.md; summarize the stable design impact there and put granular logs in local notes. - If a subagent produces findings, the main agent must review them before converting them into root docs or code changes.
Suggested local note shape:
# Agent Note: <topic>
- Branch: <branch>
- Date: YYYY-MM-DD
- Scope: mainline | branch-only | scratch
- Related files: `path/a.dart`, `path/b.dart`
## Decisions
- Decision: ...
Reason: ...
Alternatives considered: ...
## Change Log
- `path/file.dart`: changed X because Y.
## Verification
- Command: `flutter test ...`
Result: pass/fail and relevant details.- Riverpod is the state boundary. Providers live in
lib/providers/. - Do not mutate Riverpod state in place. Replace maps and lists with copied values.
- Request collection state is a
Map<String, RequestModel>?owned byCollectionStateNotifier. - Request ordering is separate in
requestSequenceProvider. - Selection is separate in
selectedIdStateProvider. - UI widgets should read providers and dispatch intent to notifiers. Keep persistence and network work out of widgets.
Correct update pattern:
state = {...state!, id: updatedModel};
ref.read(requestSequenceProvider.notifier).state = [...updatedIds];Avoid:
state![id] = updatedModel;
ref.read(requestSequenceProvider).add(id);- App models live in
lib/models/. - Core HTTP, auth, and response models live in
packages/better_networking/. - Environment models live in
packages/apidash_core/. - AI request models live in
packages/genai/. - Models use Freezed/json_serializable unless there is an established local exception, such as
SettingsModel. - After changing a Freezed/json_serializable source model, run generation and include the generated files.
- Keep JSON backwards-compatible for persisted Hive data. Add nullable/defaulted fields and migration-safe parsing.
- Hive is the collection, environment, history, and Dashbot persistence layer.
- Use
HiveHandlerfromlib/services/hive_services.dart. - Do not write request, environment, history, or Dashbot state directly through raw files or ad hoc storage.
- Root settings live in shared preferences through
lib/services/shared_preferences_services.dart. - Desktop workspaces use a user-selected Hive directory. Mobile uses
Hive.initFlutter(). CollectionStateNotifier.saveData()controls whether responses are stored, based onSettingsModel.saveResponses.
Hive boxes:
| Box | Content |
|---|---|
apidash-data |
Request collection and request ids |
apidash-environments |
Environment models and environment ids |
apidash-history-meta |
History metadata and history ids |
apidash-history-lazy |
Full history request snapshots |
apidash-dashbot-data |
Dashbot conversation data |
CollectionStateNotifier.sendRequest()is the app-level request execution coordinator.- It runs pre-request scripts, substitutes environment variables, validates the request, starts terminal logging, calls
streamHttpRequest, updates request state, writes history, then runs post-response scripts. packages/better_networking/lib/services/http_service.dartowns HTTP, GraphQL, multipart, auth application, cancellation, and streaming response handling.cancelHttpRequest(id)delegates toHttpClientManager.- Streaming is MIME-driven through
kStreamingResponseTypes; do not add protocol-specific behavior in UI widgets.
- Environment state is owned by
EnvironmentsStateNotifier. - Global variables use
kGlobalEnvironmentId. - Active variables are computed by
availableEnvironmentVariablesStateProvider. - Substitution should go through
substituteHttpRequestModel,substituteVariables, or related helpers inlib/utils/envvar_utils.dart. - Scripts may update active environment values through the notifier callback.
- Pre-request and post-response scripts are JavaScript executed by
JsRuntimeNotifier. - The JS runtime injects request, response, and environment data, then sanitizes results before turning them back into typed models.
- Script logs and errors go to
terminalStateProvider. - Terminal entries are append-only UI state with structured network, JS, and system payloads.
- Desktop uses
Dashboardwith a navigation rail andIndexedStack. - Mobile uses
MobileDashboard,PageBranch, bottom navigation, and mobile-specific request/response pages. HomePageswitches betweenDashboardSplitViewand mobileRequestResponsePageusingcontext.isMediumWindow.- Reusable design primitives belong in
packages/apidash_design_system. - Feature widgets belong near their feature under
lib/screens/or inlib/widgets/when they are truly reusable. - Preserve desktop and mobile behavior unless the task is explicitly platform-scoped.
lib/importer/importer.dartis the root import facade for cURL, Postman, Insomnia, and HAR.- Format-specific parsing belongs in the corresponding package or
packages/apidash_core/lib/import_export/. - Importers should return
HttpRequestModeldata and leave collection insertion to app-level state notifiers. - OpenAPI import assistance currently lives in Dashbot services, not in the generic
ImportFormatenum.
CodegenLanguageinlib/consts.dartis the enum source of truth.lib/codegen/codegen.dartis the router.- Language implementations live under
lib/codegen/<language>/. - Most generators use templates and shared codegen utilities.
- Adding a generator requires enum entry, router registration, implementation, UI/dropdown availability if needed, and tests under
test/codegen/. - Codegen is for HTTP requests. AI and GraphQL codegen have explicit UI messages that say they are unavailable.
- AI request execution flows through
packages/genai. AIRequestModel.httpRequestModelconverts provider-specific AI requests into HTTP requests through provider adapters.executeGenAIRequestandstreamGenAIRequestreusebetter_networking.- Dashbot chat state lives in
lib/dashbot/providers/chat_viewmodel.dart. - Dashbot action application must go through services/notifiers, not directly mutate request maps.
- Prompt construction belongs in
lib/dashbot/services/agent/prompt_builder.dartand prompt files underlib/dashbot/prompts/.
General:
- Prefer local, deterministic tests.
- Use existing fixtures in
test/models/and package test fixture folders. - Put reusable sample models in dedicated fixture files instead of recreating large objects inline.
- Use
mocktailand provider overrides for external dependencies. - Dispose
ProviderContainerinstances in teardown. - Avoid external network. A scoped loopback server is acceptable only for code whose production contract is loopback-based, and it must bind to loopback, use ephemeral ports when possible, and close in teardown.
Model tests:
- Test
copyWith,toJson,fromJson, getters, and immutability assumptions. - Keep expected JSON in fixture constants.
- Run build generation before asserting generated serialization behavior.
Provider tests:
- Override dependencies with fakes/mocks.
- Verify state replacement, selected ids, sequence providers, unsaved flags, and persistence calls.
- Avoid testing a provider through a full widget tree when a provider container test can isolate the behavior.
Widget tests:
- Match existing widget test style in
test/widgets/andtest/screens/. - Pump with the providers/theme helpers already used in the repo.
- Check desktop and mobile branches when changing responsive layout.
Codegen tests:
- Use existing request fixture models.
- Group by method or language family.
- Compare generated strings exactly with raw multiline expected strings.
- Keep deterministic boundaries where a generator needs multipart boundaries.
Networking tests:
- Test request construction, auth handling, cancellation, streaming, and response conversion at the package layer when possible.
- Keep production HTTP abstractions injectable or mockable.
Dashbot and AI tests:
- Mock
ChatRemoteRepositoryor GenAI-facing services. - Assert actions and request updates rather than relying on real model calls.
- Keep prompt-shape tests focused on the produced context and task text.
Every working agent must update docs when a change affects future work. Use this checklist before finishing:
- Did command usage change? Update
AGENTS.md. - Did source layout, package responsibility, data flow, model ownership, persistence, or app lifecycle change? Update
architecture.md. - Did a feature move from proposal/branch-only to mainline? Update both docs and remove any "not mainline" note that is no longer true.
- Did a generated model add/remove fields? Update architecture model and storage notes if it affects persisted JSON or request flow.
- Did tests establish a new pattern? Add it to this guide.
- Did you rely on a branch-only file? Do not document it as mainline unless the task explicitly asks for branch docs.
- Did you need granular reasoning, every-line change notes, or subagent findings? Put them in local agent notes and summarize only the stable impact in root docs.
Docs should be specific, short enough to stay useful, and tied to real source paths. Avoid broad claims such as "complete rewrite" or "new architecture" unless the repository actually changed that way.
- Running only
flutter testand assuming package tests ran. Usemelos testfor packages. - Editing generated files without updating source models.
- Mutating Riverpod maps/lists in place.
- Saving request data outside
HiveHandler. - Adding UI that works on desktop but breaks
context.isMediumWindowbranches. - Treating GSoC proposal docs as implementation.
- Documenting local branch files as
main. - Forgetting
CodegenLanguageorCodegen.getCodewhen adding a codegen target.
Before handing work back:
git status --shortreviewed.- Only intended files changed.
- Generated files updated when source models changed.
- Relevant tests/analyze run, or a clear reason recorded.
AGENTS.mdandarchitecture.mdupdated when architecture or agent workflow changed.- Mainline docs do not include branch-only implementation details.
- Detailed local decision logs, if created, are clearly labeled as local notes and are not presented as mainline architecture.