Plain is headed towards 1.0! Subscribe for development updates →

Dev updates

davegaeddert

Getting the agent to use the tools is another problem though. For some, a line in your AGENTS.md telling it to use plain agent is enough.

For claude code, right now I'm using a hook to inject it into the context. Every session includes all of the plain AGENTS instructions

davegaeddert

Trying a set of agent-specific tools in the plain CLI

  • read docs
  • see simplified source / framework APIs available
  • read AGENTS.md included in Plain
  • make (authenticated!) requests against your dev env
davegaeddert

Added a -c option for plain shell and having much better success with claude doing one-off Python debugging

davegaeddert

Playing with the starter kit style... this isn't quite there yet, but the general "plain" aesthetic I'm headed towards is inspired by older GitHub / Tailscale / PlanetScale

Shooting for something that works with standard Tailwind classes and system fonts. Lots of bg-stone-900

davegaeddert

I also made some changes to the class based views for working with objects (DetailView, UpdateView, etc)

They now use @cached_property for self.object, which makes it way more convenient to use the object anywhere in the view without worrying about whether it has been loaded

davegaeddert

Plain core also includes a new setting: APP_VERSION

This replaces ADMIN_TOOLBAR_VERSION and can (and will) be used in more places throughout the framework to point to the git sha or whatever you consider the "version" to be

davegaeddert

The plain toolbar has gotten to the point where it deserves it's own package

It's on the path to be a full-featured, extensible dev toolbar that works in local development and production

uv add plain-toolbar

davegaeddert
davegaeddert
2 weeks ago

Making a little progress on the admin UI...

  • pyproject.toml project name for branding
  • icons for sidebar nav
  • gravatar for logged in user
davegaeddert
davegaeddert
2 weeks ago

Experimenting with a MARK comment in the Plain source code, which we can render as sections when displaying docs.

Inspired by # pragma mark in Objective-C and MARK in Swift

davegaeddert

Plain 0.58.0 includes completely rewritten CSRF protection — no more {{ csrf_input }} needed!

This mostly relies on the modern Sec-Fetch-Site header and some great research by Filippo Valsorda (https://words.filippo.io/csrf/), and the new csrf middleware in Go 1.25.

davegaeddert
davegaeddert
1 month ago

Trying to figure out how to make a framework AI-friendly without locking in to specific providers or APIs.

Right now it seems like generating prompts + CLI tools can get you pretty far! Works with IDE agents too — just copy the prompt or tell it to run the command itself

davegaeddert
davegaeddert
1 month ago

Plain now ships with plain install and plain upgrade commands.

In some ways these are glorified AI prompt generators! But integrating with coding agents in this way leaves API keys and control completely in your hands. Use any provider or tool you want.

davegaeddert

From seeing a problem to fixing it, with the new opentelemetry instrumentation, plain-observer, and plain observer diagnose.

What else can we do if we embrace coding agents?!

davegaeddert

Models in plain no longer support custom primary keys. Everything gets a bigint auto id field!

Time will tell whether more is really needed here, but in most cases you shouldn't need to customize primary keys in new apps and this sets a clear expectation across all of Plain.

davegaeddert

When using plain-dev, your dev "services" now auto-start in the background any time they are required (perfect for a database running in a docker container).

This feels like a better DX for people, but also makes it more agent-friendly so you and claude can work side-by-side.

davegaeddert

The admin toolbar shows exception tracebacks automatically when you break something.

This appears on top of your regular error view, so you never forget what your users are seeing in these situations!

davegaeddert

plain-code now uses @biomejs v2 for a no-config formatting and linting of JS files. Just run plain fix

davegaeddert
davegaeddert
2 months ago

Plain now supports a single DATABASE instead of multiple DATABASES. This drastically simplifies a few areas of the framework.

Multiple db support can always come back if it proves to be a need, and by then it may take a different form than it has today!

davegaeddert
davegaeddert
2 months ago

The future of dependency updates?

Here's a preview of uvx plain-upgrade and how it works...

Video and longer post on X →

davegaeddert

Experimenting with a plain help command that lists out all available commands and options... one more step towards figuring out what makes a framework "AI-friendly"

davegaeddert
davegaeddert
3 months ago

plain.pytest 0.8.0 includes a new testbrowser fixture — this brings together playwright, pytest-playwright, and gunicorn to start running browser tests with no additional setup

davegaeddert

The plain-importmap package is being removed for now. The implementation wasn't quite right, and it's not totally clear that it's actually needed.

In practice, plain-esbuild (bundling) has been more useful, and plain-vendor can be used when creating importmaps manually.

davegaeddert

Elements are getting a syntax update! Now it looks more like jsx, with single braces to distinguish Python variables.

davegaeddert

The plain fix command now uses Biome to lint and format javascript, json, and css files. Combined with ruff for python, it's an all-in-one preconfigured toolset for code formatting.

davegaeddert

The updated admin toolbar

  • goes full width
  • shows request, url, and view info
  • tracks sql queries across requests
  • can show custom panels
davegaeddert

More breaking changes! The request GET and POST have been replaced by query_params and data (which can now parse JSON).

davegaeddert

The plain.api package is being reworked!

Plain itself is even more JSON-friendly than before, and the new plain.api views bring it all together with API keys and (optional) OpenAPI/swagger.json generation

davegaeddert

The first plainx community package is plainx-sentry (integration with Sentry).

We aren't planning to maintain official, first-party integrations for other commercial services... but we could provide some kind of vetted directory that includes them!

davegaeddert

Third-party packages will use the plainx namespace (instead of plain). This should help distinguish between official and community, and remove some decision making around naming.

Both use PEP 420 "implicit namespaces" so the end result is a clean from plainx import {pkg}