gt4atproto: a dedicated environment for AT Protocol

The AT Protocol is meant to offer a flexible foundation for social media. For example, a key proposition is to enable the individual to control the algorithm of what is being presented. Of course, there is no single algorithm. There can be many. These algorithms require programming. And programming benefits from dedicated environments.

gt4atproto is such a dedicated environment for AT Protocol. It is build on top of Glamorous Toolkit (GT). The main purpose of GT is to enable people to create custom experiences that are specific to a system or technology. We call this Moldable Development.

"Sounds intriguing. But what does a dedicated environment mean, really?"

Let's take a tour. We'll start from the user visible layers and then list the more technical ones.

Posting and replying on Bluesky

Bluesky is the first large server based on AT Protocol. So, naturally we want a client interface to interact with it. Only this client takes a slightly different take than might be expected.

A central component in GT is Lepiter, a moldable knowledge management system. Lepiter is made of snippets. These snippets can be of different types and are themselves programmable from within the environment.

So, now we have a Bluesky post snippet. In the screenshot below, you see a post snippet right in the middle of a Lepiter page from a private knowledge base. Obviously, the snippet allows you to post from different users that you can choose from the bottom right.

A Bluesky post in the middle of a Lepiter page.

But there is more than meets the eye. Posting on social media is not complete without the ability to post threads. If you have multiple post snippets in the same page, posting from the first one will make the second automatically be a reply to the first one. Posting the second one will make the third be a reply to the second one, and so on. And like this you get a flexible thread composing mechanism that is embedded right in your private knowledge base.

Composing Bluesky threads, including attachments.

Exploring server data interactively

Editing posts from inside a Lepiter knowledge base is already interesting, but a moldable environment gets even more interesting when you get to the programmable parts.

To post to a remote server we need a client. To get a client you first need to login. Here we see a snippet for logging into a AT Protocol server. Specifically, it's logging with a user and password into Upon the successful login, the snippet also makes an initial query to the server for This then returns a response that is automatically transformed into an instance of AppBskyActorDefsProfileViewDetailed GtApModelEntity subclass: #AppBskyActorDefsProfileViewDetailed uses: TAppBskyActorDefsProfileViewDetailed instanceVariableNames: 'atpDid atpHandle atpDisplayName atpDescription atpAvatar atpBanner atpFollowersCount atpFollowsCount atpPostsCount atpIndexedAt atpViewer atpLabels' classVariableNames: '' package: 'Gt4AtProtoGeneratedCode' which is then shown in an inspector on the right. The inspector, moldable as it is in GT, shows multiple views for the object, one of which is showing the stream of post cards.

On the left we have a login snippet. Upon logging in, we get an inspector on the user's profile object.

The inspector shows other views as well. For example, here we see the list of users the authenticated user is Following. Selecting a user from the list shows another inspector on the corresponding AppBskyActorDefsProfileViewDetailed GtApModelEntity subclass: #AppBskyActorDefsProfileViewDetailed uses: TAppBskyActorDefsProfileViewDetailed instanceVariableNames: 'atpDid atpHandle atpDisplayName atpDescription atpAvatar atpBanner atpFollowersCount atpFollowsCount atpPostsCount atpIndexedAt atpViewer atpLabels' classVariableNames: '' package: 'Gt4AtProtoGeneratedCode' instance. In this case, the inspector shows a list of Compact posts.

A list of follwed users. Selecting a user shows the followed user's details on the right.

Of course, these abilities apply to other objects as well. For example, an inspector over a post object shows a thread view.

A thread of a post.

Creating custom views

These custom views can be created live, directly when inspecting objects. For example, below we see the thread view, and next to it the source code of the view.

A view can be programmed live.

These views are rather central in Moldable Development and they bridge the gap between the internal technical details of models and external perspectives. This mechanism has a wide range of applicability, from prototyping user interfaces to technical analyses.

Prototyping algorithms

Not only the graphical part can be customized. The algorithms can be explored as well in this environment.

For example, here we have a script written in the context of a user profile object. The script finds threads written by the current user, detected as all the root posts that have replies from the same handle:

self posts
	select: [ :each | 
		each author atpHandle = self atpHandle and: [ 
			each isReply not and: [ 
				each hasRepliesFromHandle: self atpHandle]]]
Prototyping an algorithm and evaluating the output through a custom preview.

Interesting to note here is that even though the object on the right is the result of a script, it still shows a custom view with the posts as cards. This combination between scripting and immediate custom visualizations makes prototyping much easier.

Lexicons and generating code

An AT Protocol server defines the entities and methods through a so called lexicon. A lexicon itself is presently defined in a JSON file. The totality of the lexicons supported by a server offer the vocabulary through which the interaction with the server can happen at a higher level of abstraction.

gt4atproto comes with an importer for lexicons that produces a model. For example, in the picture below we see the result of importing the lexicons from github/bluesky-social/atproto. In the middle we see an inspector on a GtApLexicons Object subclass: #GtApLexicons instanceVariableNames: 'documentsById definitionsById' classVariableNames: '' package: 'Gt4AtProto-Lexicon-Importer' object showing the dependencies between lexicon objects. Selecting an object shows the details, including the original JSON declaration:

Importing and browsing lexicon definitions.

We use this model to generate the code for objects and methods as well as for the client with which to interact with the server.

Editing lexicon files

Lexicons are central to the AT Protocol, but building and maintaining lexicons can be quite difficult, especially when one has to edit plain JSON files.

The good news is that the idea of Moldable Development applies not only to how we read systems, but also to how we edit them. To this end, gt4atproto includes dedicated editors for lexicon files.

Take a look at the screenshot below.

Editing lexicon files.

On the left we see an editor on the record.json file. As one might expect from a typical editor, the JSON is highlighted. But look closer. Notice how the app.bsky.embed.record id is highlighted differently from other strings. That's because the editor understands the lexicon model.

This understanding is leveraged in other ways as well:

Whenever there is a reference to a lexicon definition, a circle appears next to it. Clicking that circle shows an editor on that definition to the right. In our example, the second pane shows the definition of app.bsky.feed.defs#generatorView spawned from the first pane.

The completion also benefits from the lexicon model. For example, in the screenshot above we see a completion in the reference value showing the matching alternatives from all definitions.

Such an editor is particularly interesting when it is considered in combination with the rest of the exploratory capabilities of the environment.

How to get the environment

Presently, the code is hosted in a repository external to GT. To build the environment, load the script in Glamorous Toolkit following the instructions from the gt4atproto page:

Metacello new
	repository: 'github://feenkcom/gt4atproto:main/src';
	baseline: 'Gt4AtProto';
#BaselineOfGt4AtProto asClass loadLepiter

This script loads both the code and a dedicated knowledge base. Once loaded, you also get a separate button in the home tab from which to open the knowledge base.

A card in the home tab that spawns the gt4atproto knowledge base.

Closing remarks

The current version of gt4atproto is the result of some three weeks of work. More is possible, but it already shows how a dedicated environment can cover interacting with AT Protocol from multiple perspectives. Some of these, like posting from a snippet inside a knowledge base, can be perceived to be end-user needs. But others, like generating code or browsing lexicon files with editors with custom completion and highlighting are more likely to be associated with a programmer's wishes. Yet, they all live seamlessly in the same environment.

Such an integrated environment complements the idea behind the AT Protocol of empowering individuals to control how they are exposed to social media through algorithmic choices. At the same time, it also shows how Moldable Development has implications that go well beyond the immediate technical aspects of a software system.