Skip to content

Instantly share code, notes, and snippets.

@MovGP0
Last active January 19, 2026 15:09
Show Gist options
  • Select an option

  • Save MovGP0/b6ff682c5622be9c23e8f19c8eccfdce to your computer and use it in GitHub Desktop.

Select an option

Save MovGP0/b6ff682c5622be9c23e8f19c8eccfdce to your computer and use it in GitHub Desktop.
AGENTS File Examples

Issue tracking

Use Beads (bd) for issue tracking.

Purpose: Git-native task & memory system for long-running coding agents.
Storage: .beads/ (JSONL, versioned by git).
Model: DAG of work items with dependencies.
Rule:

  • Create tasks from user instructions
  • Agent always queries bd ready before starting work.
bd init                     # initialize beads in repo (creates `.beads/` folder)
bd init --stealth           # local-only (no commit)
bd list                     # List all tasks
bd ready                    # List unblocked tasks (agent entry point)
bd show <id>                # Show full task
bd dep add <child> <parent> # Add dependency (child blocked by parent)
bd dep add bd-101 bd-100    # Task 101 is blocked by task 100
bd sync                     # Sync `.beads/` with branch & remote

Help

bd help                     # Full CLI reference; list commands
bd help create              # Get help for `create` command

Create Task

bd create --title "Title" --description "Description" --priority 0

Title is of the form:

<scope>: <concrete action>

Description is of the form:

Goal:
Definition of Done:
Notes:

When we need to change business logic, we also need a unit test. Create a required sub-task for the unit test implementation. The unit test needs to test the intention (use case) of the user and execute successully.

Task ID Structure

bd-a3f8          # Epic
bd-a3f8.1        # Task
bd-a3f8.1.1      # Sub-task

Workflow

  1. bd ready
  2. Select highest-priority ready task
  3. bd show <id>
  4. Execute work
  5. Update / create follow-up tasks
  6. Use bd sync to syncronize beads database with JSONL file in the .beads/ folder
  7. Commit code + .beads/
  8. Repeat

Priorities

Priority Meaning
0 Critical path / blocking
1 High
2 Normal
3 Low
4 Backlog

Failure Modes to Avoid

  • Working without a bead
  • Working on blocked beads
  • Creating tasks without dependencies
  • Letting .beads/ drift from git

Coding Style & Naming Conventions

  • Use Allman brackets. Also use Allman brackets for one-line code lines.
  • Indentation: spaces only; C# 4 spaces; XML/JSON/props 2 spaces.
  • Names: PascalCase for public members and constants; instance fields _camelCase; static fields s_camelCase; System.* usings first; prefer file-scoped namespaces and implicit usings.
  • C# prefs: use var when type is obvious; favor object/collection initializers and null-propagation.
  • Nested classes are only allowed for unit tests with the TestOf attribute will cause a build error otherwise. Avoid nested classes. Private nested records are allowed.

Line endings and encodings

  • When using PowerShell to edit a file, use \r\n (CRNL) line endings. Use UTF-8 BOM Encoding. Example:
Out-File "Hello World!\r\n" -FilePath 'Hello.txt' -Encoding utf8BOM
  • Python and Rider tools require \n (LF) as line ending; they convert to CRNL on Windows automatically.

Architecture

  • Follow SOLID principles, favor composition over inheritance, and use dependency injection.
  • Ensure high cohesion within modules and low coupling between them.

MessagePipe

  • Documentation: https://github.com/Cysharp/MessagePipe
  • Use the Publisher/Subscriber pattern to communicate between components.
  • Inject IPublisher<T> to publish and ISubscriber<T> to receive messages.
  • Prefer sealed record types for commands and events.
  • Message naming uses suffixes based on role (Command, Event, Query, Response).
    • Examples: UpdateSceneCommand, SceneUpdatedEvent, GetScenesQuery, ScenesListResponse.
  • Place messages (Command, Event, Query, Response types) in the Messages folder.

Model View Behavior Pattern

Architecture (General)

  • Use Screaming Architecture principles: organize by feature/domain, not technical layers.
  • Place shared code (services, datatypes, translations) in a dedicated/shared project.
  • Follow SOLID principles, favor composition over inheritance, and use dependency injection.
  • Ensure high cohesion within modules and low coupling between them.
  • For each UI component, keep View, ViewModel, and Behaviors in their own folders/projects and register them together in a DependencyInjection.cs file.

Behaviors (Custom)

  • Behaviors are custom classes; they do not come from a third-party library.
  • Implement one behavior per class and place them in a Behaviors folder with a Behavior suffix.
public interface IBehavior<in TViewModel>
{
    void Activate(TViewModel viewModel, CompositeDisposable disposables);
}
  • Behaviors can:
    • Create ReactiveCommands.
    • Subscribe to ViewModel property changes.
    • Subscribe to MessagePipe messages.
  • Services can be injected into a Behavior via constructor injection.
public sealed class SearchSceneBehavior : IBehavior<SceneViewModel>
{
    private readonly ISubscriber<UpdateScenesCommand> _updateScenesCommandSubscriber;

    public SearchSceneBehavior(ISubscriber<UpdateScenesCommand> updateScenesCommandSubscriber)
    {
        _updateScenesCommandSubscriber = updateScenesCommandSubscriber;
    }

    public void Activate(SceneViewModel viewModel, CompositeDisposable disposables)
    {
        viewModel
            .WhenAnyValue(vm => vm.SearchText)
            .Subscribe(_ => DoSomething())
            .DisposeWith(disposables);

        viewModel.SearchTextCommand
            .Subscribe(_ => DoSomething())
            .DisposeWith(disposables);

        _updateScenesCommandSubscriber
            .Subscribe(_ => DoSomething())
            .DisposeWith(disposables);
    }
}
  • Behaviors are injected as IEnumerable<IBehavior<TViewModel>> and activated from WhenActivated.
public sealed class SomeViewModel : ReactiveObject, IActivatableViewModel
{
    private readonly IEnumerable<IBehavior<SomeViewModel>> _behaviors;

    public SomeViewModel(IEnumerable<IBehavior<SomeViewModel>> behaviors)
    {
        _behaviors = behaviors;

        this.WhenActivated(disposables =>
        {
            foreach (var behavior in _behaviors)
            {
                behavior.Activate(this, disposables);
            }
        });
    }
}

ReactiveUI

  • We use ReactiveUI with ReactiveUI.Fody.Helpers. For implementing INotifyPropertyChanging and INotifyPropertyChanged you may derive entities and ViewModels from the ReactiveObject base class. Example:
public sealed class SomeClass : ReactiveObject
{
    [Reactive] public string Name { get; set; }
}
  • We use ReactiveMarbles.ObservableEvents for event subscriptions:
someObject.EventName += OnHandleEvent; // old method; AVOID
// at the beginning of the file in the using block (when not implicitly used)
using ReactiveMarbles.ObservableEvents;

// subscription using ObservableEvents
someObject.Events().EventName
    .Subscribe(eventArgs => OnHandleEvent(eventArgs))
    .DisposeWith(Disposables); // assuming property with CompositeDisposable Disposables { get; } = new(); signature.

ReactiveUI

  • Documentation: https://reactiveui.net/docs/
  • Use ReactiveUI for the MVVM pattern.
  • Views:
    • Views are named SomeView.xaml and implement IViewFor<TViewModel> or use the [IViewFor<TViewModel>] attribute.
    • All Views (Pages, Controls) should either have the [IViewFor<TViewModel>] attribute or derive from a Reactive* control (e.g., ReactiveContentPage).
    • Make sure to set x:TypeArguments, x:Class, and x:DataType as needed:
<maui:ReactiveContentView x:TypeArguments="local:MyViewModel"
                         xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                         xmlns:maui="using:ReactiveUI.Maui"
                         x:Class="local:MyView"
                         x:DataType="local:MyViewModel">
  • ViewModels:
    • ViewModels are named SomeViewModel and derive from ReactiveObject.
    • Implement IActivatableViewModel and activate behaviors in the constructor:
public sealed class SomeViewModel : ReactiveObject, IActivatableViewModel
{
    public SomeViewModel(IEnumerable<IBehavior<SomeViewModel>> behaviors)
    {
        this.WhenActivated(this.ActivateBehaviors);
    }
}
  • Collections should use ObservableCollectionExtended<T> or other suitable DynamicData collection types for UI updates.
  • Commands:
    • Use ReactiveCommand<Unit, Unit> for user actions (e.g., button clicks).
    • Commands are created in Behaviors and assigned to the ViewModel. Initialize fields to DisabledCommand.Instance for binding.
    • ReactiveCommand fields should not use a Command suffix (use OpenFile, not OpenFileCommand).
    • Always subscribe to Execute() and ThrownExceptions:
var someCommand = ReactiveCommand
    .Create(() => { /* ... */ }, canExecute, RxApp.MainThreadScheduler)
    .DisposeWith(disposables);

someCommand.ThrownExceptions
    .Subscribe(ex => logger.LogError(ex, "Error while executing the command"))
    .DisposeWith(disposables);

viewModel.SomeCommand = someCommand;

someCommand.Execute().Subscribe();
  • If a Behavior writes to the ViewModel, schedule it on the UI thread (e.g., RxApp.MainThreadScheduler.Schedule(...)).
  • Prefer commands and data binding over event handlers:
<!-- incorrect -->
<Button OnClick="OnSettingsClicked" />

<!-- correct -->
<Button Command="{Binding NavigateToSettingsCommand}" />
  • Ensure the binding context points to the ViewModel, not the control itself.
  • Events and disposal:
    • Use .Events().EventName to convert events to IObservable<TArgs>.
    • Dispose all subscriptions with CompositeDisposable or SerialDisposable and .DisposeWith(disposables).

ReactiveUI.SourceGenerators

public partial class MyReactiveClass : ReactiveObject
{
    [Reactive]
    private string _name = string.Empty;

    [ReactiveCommand]
    private async Task SaveAsync()
    {
        // ...
    }
}
  • For commands returning values, subscribe to the command result:
[ReactiveCommand]
private Task<TResult> SomeCommandAsync(TArgument argument)
{
    TResult result = /* ... */;
    return Task.FromResult(result);
}

// subscription (e.g., in a Behavior)
viewModel.SomeCommand
    .Subscribe(result => { /* ... */ })
    .DisposeWith(disposables);
  • Source generators can coexist with ReactiveUI.Fody during migration.

ReactiveUI.Fody (Legacy)

public sealed class MyViewModel : ReactiveObject
{
    [Reactive]
    public string Name { get; set; }
}
  • Note: ReactiveUI.Fody does not support inline auto-property initializers in generic types. Initialize those in the constructor instead.

Scripting

The following scripting engines are installed:

Rust script

echo 'println!("Hello, World!");' > hello.rs
rust-script hello.rs

LinqPad 9

lprun hello.linq

PowerShell

pwsh -NoLogo -NoProfile -File Hello.ps1 

Python

python hello.py

FriCAS for solving math problems via WSL2

# create ./.temp/Invoke-FriCASInput.ps1
function Invoke-FriCAS {
  param(
    [Parameter(Mandatory=$true)]
    [string] $InputFile
  )

  $windowsPath = (Resolve-Path $InputFile).Path

  $command = @"
set -euo pipefail
INPUT=\$(wslpath '$windowsPath')
fricas -nosman < "\$INPUT"
"@

  $output = wsl.exe bash -lc $command
  if ($LASTEXITCODE -ne 0) {
    throw "FriCAS failed with exit code $LASTEXITCODE"
  }
  return $output
}

# invoke
Invoke-FriCAS -InputFile .\solve.input
  • When you need to execute a script, first create the script file in a .temp/ folder.
  • Delete the folder once you are finished.

Terminal Usage

  • prefer executing pwsh for executing scripts
  • Do not use pwsh to start python and do not use python to start pwsh; use pwsh or python directly instead
  • be careful with escape characters. Especially when you need to double-escape a character (ie. regular expressions in an pwsh script)
  • When executing pwsh, use -NoLogo -NoProfile arguments to prevent the user profile from loading.

Bad example:

pwsh.exe -Command "..."

Good example:

pwsh.exe -NoLogo -NoProfile -Command "..."
  • When executing Python code, use python directly. Do not use pwsh to invoke python.

Bad example:

pwsh.exe -NoLogo -NoProfile -Command "python - ...

Good example:

python - ...
  • This is a Windows system, so

    1. when using PowerShell, use CRNL (\r\n) for line endings explicitly
    2. when using Python or Rider tools, use NL (\n) for line endings; they will automatically be interpreted as CRNL
  • ripgrep rg command is installed

  • prefer Rider tools over terminal commands, when a tool that can solve a given task is available.

Testing guidelines

  • Name the test class after the object that is beeing testet, followed by "Tests".
  • Prefer xUnit for unit testing

Test setup

  • You may need to initialize a unit test with a ServiceLocator. Especially for logging:
[TestOf(typeof(SettingsProvider), nameof(SettingsProvider.LoadSettings))]
public sealed class LoadSettingsTests: IDisposable
{
    public LoadSettingsTests(ITestOutputHelper testOutputHelper)
    {
        ServiceLocator.Cleanup();
        ServiceLocator.Initialize(services =>
        {
            services.AddLogging(logger =>
            {
                logger.SetMinimumLevel(LogLevel.Debug);
                logger.AddXUnit(testOutputHelper);
            });
        });
    }

    public void Dispose() => ServiceLocator.Cleanup();

    // tests come here...
  • The name of a test (Fact/Theory) should start with the name "Should", followed by the expected result and the action taken. Setting the DisplayName property improves readability.
[Fact(DisplayName = "Should return user settings when invoked")]
public void ShouldReturnUserSettingsWhenInvoked()
  • Structure the unit tests using // Arrange, // Act and // Assert comments. You may also use // Cleanup or // Arrange & Act or // Act & Assert in rare situations.
  • Name the object beeing testet as subject and the (primary) result value result:
// Arrange
var subject = new SomeTypeUnderTest();

// Act
var result = subject.DoSomething();
  • Use Shouldy for assertions. Use one assertion only, but you may use ShouldSatisfyAllConditions when multiple assertions are required:
result.ShouldSatisfyAllConditions(
    () => /* first assertion */,
    () => /* second assertion */,
    () => /* third assertion */,
    // add more assertions as required
);
  • You may also nest assertions:
result.ShouldSatisfyAllConditions(
    () => result.Value.ShouldNotBeNull().ShouldBe("foobar"),
    // add more assertions as required
);

Usage of [TestOf] Attribute

  • Use [TestOf(typeof(ClassName))] on test classes to indicate the class under test.
  • Use [TestOf(typeof(ClassName), nameof(ClassName.MethodName))] or [TestOf(typeof(ClassName), nameof(ClassName.PropertyName))] for nested test classes.
  • Use the ILObjectNames class for special .NET objects like operators and constructors.

Examples:

[TestOf(typeof(TypeUnderTest)]
public static class TypeUnderTestTests
{
    [TestOf(typeof(TypeUnderTest), ILObjectNames.Constructor)]
    public sealed class ConstructorTests { /* ... */ }

    [TestOf(typeof(TypeUnderTest), ILObjectNames.Deconstructor)]
    public sealed class DeconstructorTests { /* ... */ }

    [TestOf(typeof(TypeUnderTest), ILObjectNames.Indexer)]
    public sealed class IndexerTests { /* ... */ }

    [TestOf(typeof(TypeUnderTest), ILObjectNames.op_Addition)]
    public sealed class AdditionOperatorTests { /* ... */ }

    [TestOf(typeof(TypeUnderTest), ILObjectNames.op_MultiplicationAssignment)]
    public sealed class MultiplicationAssignmentOperatorTests { /* ... */ }

    [TestOf(typeof(TypeUnderTest), ILObjectNames.op_GreaterThanOrEqualAssignment)]
    public sealed class GreaterThanOrEqualAssignmentOperatorTests { /* ... */ }

    [TestOf(typeof(TypeUnderTest), ILObjectNames.op_Implicit)]
    public sealed class ImplicitOperatorTests { /* ... */ }

    [TestOf(typeof(TypeUnderTest), ILObjectNames.op_Explicit)]
    public sealed class ExplicitOperatorTests { /* ... */ }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment