Status Week 34

Foundry

  • Spent a bit of time working out how we can enable selection of app patterns in Foundry. The goal here would be to have some very common libadwaita usage patterns available for selection in the new-project guide.

    Ultimately it will rely on FoundryInputCombo/FoundryInputChoice but we’ll have to beef it up to support iconography.

  • Finish up a couple speed-runs so they can be uploaded to to gitlab. chergert/assist and chergert/staged are there and can serve as an example of how to use the libfoundry API.

  • A big portion of this week has been figuring out how I want to expose tweaks from libfoundry into applications. There are a lot of caveats here which make it somewhat tricky.

    For example, not every application will need every toggle, so we need a way to filter them. GListModel is probably our easiest way out with this, but we’ll likely need a bit more control over provenance of tweaks here for filtering.

  • Tweak engine has a new “path” design which allows us to dynamically query available tweaks as you dive down deeper into the UI. This is primarily to help avoid some of the slower parts of the tweaks engine in GNOME Builder.

    Also, to help support this, we can define tweaks using static data which allows for registration/query much faster. For example, there is no need to do UI merging since that can happen automatically.

    There are also cases where you may need to register tweaks which are more complex than simple GSettings. We should be able to accommodate that just fine.

  • Added API for add/remove to Git stage. Much simpler than using the libgit2 index APIs directly, for the common things.

    We may want to add a “Stage” API at some point. But for now, the helpers do the job for the non-partial-stage use-case.

    Just foundry_git_vcs_stage_entry (vcs, entry, contents) where the entry comes from your status list. You can retrieve that with foundry_git_vcs_list_status (vcs). If you are brave enough to do your own diff/patch you can implement staging lines with this too.

    However, that is probably where we want an improved stage helper.

  • Added API for creating commits.

    Much easier to do foundry_git_vcs_commit (vcs, msg, name, email) than the alternatives.

  • Running LLM tools can now be done through the conversation object which allows for better retention of state. Specifically because that can allow the conversation to track a history object other than a simple wrapped FoundryLlmMessage.

    For example, some message subclasses may have extra state like a “directory listing” which UI could use to show something more interesting than some text.

  • Simplify creating UI around FoundryLlmConversation with a new busy property that you can use to cancel your in-flight futures.

  • Fixed an issue where running the LLM tool (via subprocess) would not proxy the request back to the parent UI process. Fixing that means that you can update the application UI when the conversation is running a tool. If you were, for example, to cancel the build then the tool would get canceled too.

  • Made the spellcheck integration work the same as we do in Builder and Text Editor which is to move the cursor first on right-click before showing corrections.

Libspelling

  • New release with some small bugfixes.

Levers

  • Another speed run application which is basically the preferences part of Builder but on top of Foundry. The idea here is that you can just drop into a project and tweak most aspects of it.

    Not intended to be a “real” application like the other speed-runs, but at least it helps ensure that the API is relatively useful.

Status Week 33

This week is still largely focused on finalizing API/ABI for the 1.0 of Foundry in a few weeks.

Foundry

  • Did a bunch of work on LLM completion and and conversation APIs. They are not focused on supporting everything possible but instead making some of the common stuff extremely simple. That goes for both the model size of things and the UI side of things.

    For example, heavy usage of GListModel everywhere we can.

  • Created new abstractions for LlmTool, LlmToolProviders, and the actual call of a tool (aptly, LlmToolCall). One reason this all takes so much time to scaffold is that you want to allow some amount of flexibility when connecting models, but also avoid too much API surface area.

    I think I’ve managed to do that here.

  • Landed Ollama implementation of the FoundryLlmConversation API. The ollama server appears to be stateless, which means copying the conversation over-and-over as you go. I guess this at least gives you an idea of your context window.

  • Setup a couple tool call implementations to test out that infrastructure. For example, it’s really easy to tell the model that you build with build tool and then provide it the results.

  • Fixed some licensing issues where I mostly just forgot to update the headers when copying them over. Things should be in a good place now for distributions to adhere to their SPDX rules.

  • Language settings now have a very last resort setting which are the “defaults” we ship with the library. That is just sensible stuff like using 4 spaces for tabs/indent in Python.

    Settings at any layer can override these values.

  • Lots of work on project templates. We have both GTK 4 and Adwaita templates again. They support C/Python/rust/JavaScript like Builder does too.

    But this time I tried to go a bit further. They should have a bunch of integration bits setup which we didn’t get to before.

  • Setup an example Flatpak manifest for applications wanting to use libfoundry (see examples/flatpak/) that should help get you started.

  • Setup i18n/l10n for libfoundry. I don’t think anything is consuming translations for GNOME 49 though, so mostly just gets us up and running for 50.

  • Landed some new API for working with the stage/index within FoundryGitVcs. Tested it with a speed-run challenge a bit later on in this report.

Assist

  • To test out the LLM APIs and ensure they can actually be used I did a speed-run to implement a “Foundry-based Developer Chat” with a time limit of two hours.

    The reality is that I’m still _much_ faster writing code with all of my templates and snippets than I thought.

    The new templates in Foundry are killer though.

  • It requires a model which supports tool calls if you want to do anything interesting with it. I’m not sure if there are models which can do both written output _and_ tool-calls which makes this a bit annoying to wait while it figures out it should call a tool.

  • While doing this, I realized a bunch of little things to fix in the LLM APIs. One piece still missing that I’d want to have in the future is the ability for specialized FoundryLlmMessage which not only have text content but typed data as well.

    For example, a tool call that is essentially a ls should really display the output as an interactive directory list and not text.

    But since this was a speed run, I did not implement that. Only made sure that the APIs could adapt to it in the future.

Staged

  • Started another speed-run app to test out the version control engine we have in Foundry. This one is basically just to replace my very quick use of git-gui to line stage patches.

    Came up with a neat way to highlight old/new versions of a file and then display them with GtkListView instead of using a source view. No reason to power up the editing infrastructure if you’ll never be editing.

Manuals

  • Discovered I wasn’t getting notifications since the move to the GNOME/ namespace so flushed out the backlog of MR there.

GtkSourceView

  • Fix click-through on the overview map which broke again during this development cycle. My fault for not reviewing and/or testing better.

  • Now that we have GNOME CI doing LSAN/ASAN/UBSAN/coverage/scanbuild I went ahead and fixed a bunch of leaks that are part of the testsuite.

    Additionally, it helped me find a few that were there in everyday code use, so that is always a lovely thing to fix.

Ptyxis

  • Merge some last minute string changes before we can’t anymore.

  • Still having to unfortunately close issues which come from Debian not sourcing /etc/profile.d/vte.sh by default, thus breaking integration features.

    The good news I hear is that will be changing before long.

  • Other good news is that Ptyxis has landed in the 25.10 builds and will also be landing in Debian unstable in the near future as the default terminal.

  • After some back-and-forth I merged support for the kgx palette as the “GNOME” palette in Ptyxis. My very hopeful desire is that this becomes something maintained by the design team. The problem is just that terminal colors are a huge piles of hacks on hacks.

  • Nightly builds should be fixed. Apparently something changed in the CI setup and since we’re under chergert/ptyxis/ and not GNOME/ it didn’t get automatically applied.

  • Some styling changed in libadwaita this cycle and I needed to adapt how we propagate our styling to tab close buttons.

    Really though, this all just needs to be redone (like Text Editor and Builder) to use var() properly in CSS.

Libspelling

  • Merged patch improving life-cycle tracking of the piecetable/b+tree regions (branches/leaves).

Sysprof

  • More code review and future feature planning so we can land GSoC things after I branch for 49 (very soon I hope).

Other

  • Turned 41, saw Stevie Ray Vaughan’s broadcaster guitar, finally had the “weird” pizza at Lovely’s fifty/fifty, jammed at MoPOP with my niece.

  • Lots of random little things this week to lend a hand/ear here or there as we get closer to release.

Week 32 Status

Foundry

This week was largely around getting the new template engine landed so it can be part of the 1.0 ABI. Basically just racing to get everything landed in time to commit to the API/ABI contract.

  • FoundryTextBuffer gained some new type prerequisites to make it easier for writing applications against them. Since Foundry is a command line tool as well as a library, we don’t just use GtkTextBuffer since the CLI doesn’t even link against GTK. But it is abstracted in such a way that the GTK application would implement the FoundryTextBuffer interface with a derived GtkSourceBuffer.

  • FoundryTextSettings has landed which provides a layered approach to text editor settings similar (but better) than we have currently in GNOME Builder. There is a new modeline implementation, editorconfig, and gsettings backed settings provider which apply in that order (with per-file overrides allowed at the tip).

    Where the settings-backed implementation surpasses Builder is that it allows for layering there too. You can have user-overrides by project, project defaults, as well as Foundry defaults.

    I still need to get the default settings per-language that we have already (and are mostly shared with Text Editor too) as reasonable defaults.

  • To allow changing the GSettings-based text settings above, the foundry settings set ... command gained support for specific paths using the same :/ suffix that the gsettings command uses.

  • Spent some time on the upcoming chat API for models so I can experiment with what is possible when you control the entire tools stack.

  • Dropped some features so they wouldn’t be part of the 1.0. We can implement them later on as time permits. Specifically I don’t want to commit to a MCP or DAP implementation yet since I’m not fond of either of them as an API.

  • The FoundryInput subsystem gained support for license and language inputs. This makes it much simpler to write templates in the new internal template format.

  • Allow running foundry template create ./FILE.template to create a set of files or project from a template file. That allows you to interate on your own templates for your project without having to have them installed at the right location.

  • Wrote new project templates for empty project, shared library project, and gtk4 projects. Still need to finish the gtk4 project a bit to match feature parity with the version from Builder.

    I very much am happy with how the library project turned out because this time around it supports Gir, Pkgconfig, Vapi generation, gi-doc, and more. I still need to get library potfile support though.

    I also wrote new templates for creating gobjects and gtkwidgets in C (but we can port to other languages if necessary). This is a new type of “code template” as opposed to “project template”. It still allows for multiple files to be created in the target project.

    What is particularly useful about it though is that we can allow projects to expose templates specific to that project in the UI. In Foundry, that means you have template access to create new plugins, LSPs, and services quite easily.

  • Projects can specify their default license now to make more things just happen automatically for contributors when creating new files.

  • Templates can include the default project license header simply now by doing `{{include “license.c”}} where the suffix gets the properly commented license block.

  • The API for expand templates has changed to return a GListModel of FoundryTemplateOutput. The primary motivator here is that I want to be able to have UI in Builder that lets you preview template before actually saving the templates to disk.

  • A new API landed that we had in Builder for listing build targets. Currently, only the meson plugin implements the FoundryBuildTargetProvider. This is mostly plumbing for upcoming features.

  • The new template format is a bit of amalgamation from a few formats that is just based on my experience trying to find a way to maintain these templates.

    It starts with a GKeyFile block that describes the template and inputs to the template.

    Then you have a series of what looks like markdown code blocks. You can have conditionals around them which allows for optionally including files based on input.

    The filename for the blocks can also be expanded based on template inputs. The expansions are just TmplExpr expressions from template-glib.

    An example can be found at:

    https://gitlab.gnome.org/GNOME/foundry/-/blob/main/plugins/meson-templates/library.project

Template-GLib

  • Found some oopsies in how TmplExpr evaluated branches so fixed those up. Last year I wrote most of a C compiler and taking a look at this code really makes me want to rewrite it all. The intermixing of Yacc and GObject Introspection is ripe for improvement.

  • Added support for == and != of GStrv expressions.

Other

  • Play CI whack-a-mole for ICU changes in nightly SDKs

  • Propagate foundry changes to projects depending on it so that we have useful flatpak manifests with minimal feature flags enabled.

  • Took a look at some performance issues in GNOME OS and passed along some debugging techniques. Especially useful for when all you got is an array of registers and need to know something.

  • Libpeas release for GNOME 49 beta

Week 31 Status

Foundry

  • Added a new gutter renderer for diagnostics using the FoundryOnTypeDiagnostics described last week.

  • Write another new gutter renderer for “line changes”.

    I’m really happy with how I can use fibers w/ GWeakRef to do worker loops but not keep the “owner object” alive. As long as you have a nice way to break out of the fiber loop when the object disposes (e.g. trigger a DexCancellable/DexPromise/etc) then writing this sort of widget is cleaner/simpler than before w/ GAsyncReadyCallback.

    foundry-changes-gutter-renderer.c

  • Added a :show-overview property to the line changes renderer which conveniently allows it to work as both a per-line change status and be placed in the right-side gutter as an overview of the whole document to see your place in it. Builder just recently got this feature implemented by Nokse and this is basically just a simplified version of that thanks to fibers.

  • Abstract TTY auth input into a new FoundryInput abstraction. This is currently used by the git subsystem to acquire credentials for SSH, krb, user, user/pass, etc depending on what the peer supports. However, it became pretty obvious to me that we can use it for more than just Git. It maps pretty well to at least two more features coming down the pipeline.

    Since the input mechanisms are used on a thread for TTY input (to avoid blocking main loops, fiber schedulers, etc), they needed to be thread-safe. Most things are immutable and a few well controlled places are mutable.

    The concept of a validator is implemented externally as a FoundryInputValidator which allows for re-use and separating the mechanism from policy. Quite like how it turned out honestly.

    There are abstractions for text, switches, choices, files. You might notice they will map fairly well to AdwPreferenceRow things and that is by design, since in the apps I manage, that would be their intended display mechanism.

  • Templates have finally landed in Foundry with the introduction of a FoundryTemplateManager, FoundryTemplateProvider, and FoundryTemplate. They use the new generalized FoundryInput abstractions that were discussed above.

    That allows for a foundry template list command to list templates and foundry template create to expand a certain template.

    The FoundryInput of the templates are queried via the PTY just like username/password auth works via FoundryInput. Questions are asked, input received, template expansion may continue.

    This will also allow for dynamic creation of the “Create Template” widgetry in Builder later on without sacrificing on design.

  • Meson templates from Builder have also been ported over which means that you can actually use those foundry template commands above to replace your use of Builder if that is all you used it for.

    All the normal ones are there (GTK, Adwaita, library, cli, etc).

  • A new license abstraction was created so that libraries and tooling can get access to licenses/snippets in a simple form w/o duplication. That generally gets used for template expansion and file headers.

  • The FoundryBuildPipeline gained a new vfunc for prepare_to_run(). We always had this in Builder but it never came over to Foundry until now.

    This is the core mechanism behind being able to run a command as if it were the target application (e.g. unit tests).

  • After doing the template work, I realized that we should probably just auto initialize the project so you don’t have to run foundry init afterwards. Extracted the mechanism for setting up the initial .foundry directory state and made templates use that.

  • One of the build pipeline mechanisms still missing from Builder is the ability to sit in the middle of a PTY and extract build diagnostics. This is how errors from GCC are extracted during the build (as well as for other languages).

    So I brought over our “PTY intercept” which takes your consumer FD and creates a producer FD which is bridged to another consumer FD.

    Then the JIT’d error extract regexes may be run over the middle and then create diagnostics as necessary.

    To make this simple to consume in applications, a new FoundryPtyDiagnostics object is created. You set the PTY to use for that and attach it’s intercept PTY to the build/run managers default PTY and then all the GAction will wire up correctly. That object is also a GListModel making it easy to display in application UI.

  • A FoundryService is managed by the FoundryContext. They are just subsystems that combine to useful things in Foundry. One way they can be interacted with is GAction as the base class implements GActionGroup.

    I did some cleanup to make this work well and now you can just attach the FoundryContexts GActionGroup using foundry_context_dup_action_group() to a GtkWindow using gtk_widget_insert_action_group(). At that point your buttons are basically just "context.build-manager.build" for the action-name property.

    All sorts of services export actions now for operations like build, run, clean, invalidate, purge, update dependencies, etc.

    There is a test GTK app in testsuite/tools/ you can play with this all to get ideas and/or integrate into your own app. It also integrates the live diagnostics/PTY code to exemplify that.

  • Fixed the FoundryNoRun tool to connect to the proper PTY in the deployment/run phase.

  • The purge operation now writes information about what files are being deleted to the default build PTY.

  • The new FoundryTextSettings abstraction has landed which is roughly similar to IdeFileSettings in Builder. This time it is much cleaned up now that we have DexFuture to work with.

    I’ve ported the editorconfig support over to use this as well as a new implementation of modeline support which again, is a lot simpler now that we can use fibers/threadpools effectively.

    Plugins can set their text-settings priority in their .plugin file. That way settings can have a specific order such as user-overrides, modelines, editorconfig, gsettings overrides, language defaults, and what-not.

  • The FoundryVcs gained a new foundry_vcs_query_file_status() API which allows querying for the, shocking, file status. That will give you bitflags to know in both the stage or working tree if a file is new/modified/deleted.

    To make this even more useful, you can use the FoundryDirectoryListing class (which is a GListModel of FoundryDirectoryItem) to include vcs::status file-attribute and your GFileInfo will be populated with the uint32 bitflags for a key under the same name.

    It’s also provided as a property on the FoundryDirectoryItem to make writing those git “status icons” dead simple in file panels.

Boxes

  • Found an issue w/ trailing \x00 in paths when new Boxes is opening an ISO from disk on a system with older xdg portals. Sent a pointer on the issue tracker to what Text Editor had to do as well here.

Libpeas

  • GJS gained support for pkgconfig variables and we use that now to determine which mozjs version to link against. That is required to be able to use the proper JS API we need to setup the context.

Ptyxis

  • Merged some improves to the custom link support in Ptyxis. This is used to allow you to highlight custom URL regexes. So you can turn things like “RHEL-1234” into a link to the RHEL issue tracker.

  • Track down an issue filed about titles not updating tab/window titles. It was just an issue with $PROMPT_COMMAND overwriting what they had just changed.

Text Editor

  • A lot of the maintainership of this program is just directing people to the right place. Be that GtkSourceView, GTK, shared-mime-info, etc. Do more of that.

    As an aside, I really wish people spent more time understanding how things work rather than fire-and-forget. The FOSS community used to take pride in ensuring the issue reports landed in the right place to avoid over burdening maintainers, and I’m sad that is been lost in the past decade or so. Probably just a sign of success.

Builder

  • Did a quick and dirty fix for a hang that could slow down startup due to the Manuals code going to the worker process to get the default architecture. Builder doesn’t link against Flatpak in the UI process hence why that did it. But it’s also super easy to put a couple line hard-coded #ifdef and avoid the whole RPC.

Libdex

  • Released 0.11.1 for GNOME 49.beta. I’m strongly considering making the actual 49 release our 1.0. Things have really solidified over the past year with libdex and I’m happy enough to put my stamp of approval on that.

Libspelling

  • Fix an issue with discovery of the no-spellcheck-tag which is used to avoid spellchecking things that are general syntax in language specifications. Helps a bunch when loading a large document and that can get out of sync/changed before the worker discovers it.

  • Fixed a LSAN discovered leak in the testsuite. Still one more to go. Fought LSAN and CI a bit because I can’t seem to reproduce what the CI systems get.

Other

  • Told Chat-GPT to spit me out a throw away script that parses my status reports and converts them into something generally usable by WordPress. Obviously there is a lot of dislike/scrutiny/distrust of LLMs and their creators/operators, but I really don’t see the metaphorical cat going back in the bag when you enable people in a few seconds to scratch an itch. I certainly hope we continue to scrutinize and control scope though.