Skip to content

Latest commit

 

History

History
111 lines (78 loc) · 6.89 KB

File metadata and controls

111 lines (78 loc) · 6.89 KB

morph_kit

Public AI agent contract for morph_kit — read by Cursor, OpenAI Codex, Aider, Devin, JetBrains Junie, and any AI tool that follows the agents.md convention.

Claude Code reads the deeper workspace config at whuppi/.claude/rules/ and whuppi/.claude/memory/ automatically — this AGENTS.md exists for every other AI tool.

Stamped from whuppi/AGENTS.template.md. Per-repo content lives in the placeholder sections; everything else is identical workspace-wide.


What this tool does

morph_kit is adaptive layout widgets for Flutter — ListDetailLayout (list + selected detail: slide-over with swipe-to-dismiss on phones, covering nav bars via an always-mounted OverlayPortal; side-by-side with a draggable, anchor-snapping divider on wide windows) and AdaptiveSplit (two always-present panes). Pane widget instances survive the compact ↔ expanded morph (GlobalKey reparenting), and a paint-visibility probe suppresses the overlay detail of inactive kept-alive tabs. Router-agnostic and state-management-agnostic — a ChangeNotifier controller is the whole integration surface.

This repo is one tool inside the whuppi workspace — a multi-tool monorepo. The workspace ships shared engineering standards, code conventions, brand identity, and build patterns that apply across every tool. They're documented in three layers:

  • Repo-specific architecture, design, reference: ./docs/
  • Workspace human-readable standards: ../docs/ (when this repo is cloned as part of the whuppi workspace) — engineering principles, decision frameworks, secret/CI patterns
  • Workspace AI-only directives: ../.claude/rules/ (Claude Code reads these automatically; other AI tools can read them as supplementary context)

If you're working on this tool standalone (cloned outside the workspace), the in-repo ./docs/ is your authority; ignore the workspace pointers.


Build and test commands

Run these after every code change. A failing test or analyzer error means the task is not done — don't suppress with // ignore:, # noqa, or --no-verify. Fix the underlying issue.

# Setup (one-time)
make hooks
fvm install && fvm flutter pub get

# Full gate
make check               # lint-shell + analyze (pkg + example) + analyze-floor + platforms +
                         # test (widget suite, host VM) + test-example (journeys)

Code style

Match the style of existing code in this repo first. Workspace-wide standards live at:

  • Engineering standards (seven questions before every decision, env-blind code, twelve-factor checklist): ../docs/universal/development-standards.md
  • Secrets and environments (GitHub Environments, branch=env, security walls, files-not-env-vars): ../docs/universal/secrets-and-environments.md
  • Python tools (SDK/CLI/MCP three-layer pattern, ruff config, hatchling): ../.claude/rules/python-shared/sdk-cli-mcp-pattern.md
  • Flutter packages (opaque boundaries, async at edges, dependency flow): ../.claude/rules/flutter-shared/package-design.md
  • Comments and doc-comments (what earns a comment, what doesn't): ../.claude/rules/universal/comments.md
  • Renaming anything (sweep all references in one session): ../.claude/rules/universal/rename-hygiene.md

When in doubt, read existing code in this repo and match it. Per-repo style consistency beats general-best-practice consistency.


Tool-specific notes

  • The overlay invariants are sacred (docs/UPDATING.md §1): the OverlayPortal is shown once and never hidden (the overlay child collapses instead — toggling trips the controller's layout-phase assertion); the paint probe evaluates during layout and reports during paint with a deferred re-show; suppression needs a rebuild pass of the inactive child. Don't "fix" any of this with timers or polling.
  • Panes mount under stable GlobalKeys — that reparenting is the state-preservation guarantee across the compact ↔ expanded morph. Anything that changes a pane's tree position must keep the same key wrapping the same builder output.
  • Core never imports components — divider / empty-state params are nullable; apps pass a shipped component or their own.
  • Pane width math lives ONLY in PaneWidthModel (shared by both widgets) — never inline resize/clamp/snap logic in a widget.
  • example/ is the integration harness — a full dummy app with nested kept-alive tab routers, URL sync, and overlay-mode list-details everywhere. Package changes must keep its journeys green (make test-example).

Data, secrets, and gitignore

This repo's .gitignore is stamped from ../.gitignore.template (workspace canonical). It already covers:

  • data/.env and every other .env flavor (only .env.example / .env.template / .env.sample are committed)
  • data/auth/ (captured tokens, cookies, OAuth credentials)
  • data/db/*.sqlite* (full app state — irreplaceable)
  • cookies*.json, *.token, *.pem, *.key
  • output/, debug/, logs/, cache/

Never commit a sensitive file even if it's somehow not gitignored — surface to the maintainer instead. The gitignore is defense-in-depth, not the only check.


Working with AI agents

  • Run the test suite before claiming completion. Always.
  • Don't add TODO comments as a substitute for fixing things. If you found it, you own it — fix in this pass or surface to the maintainer.
  • Don't add backwards-compat shims for code that hasn't shipped. Code assumes the latest schema and contracts; migrations handle old data once.
  • Don't refactor "for cleanliness" without a stated reason. Surface the suggestion before changing surrounding code.
  • No co-authored-by AI in commits. The maintainer is the author.
  • Never force-push protected branches (prod, main, dev). Never skip pre-commit hooks.

For the engineering philosophy that informs every line of code in this workspace, see ../.claude/rules/universal/dc-engineering-philosophy.md if available.


This file is stamped from whuppi/AGENTS.template.md. The placeholder sections ({{...}}) are the only parts customized per repo. Re-stamping refreshes the shared content; per-repo placeholders are preserved.