clink 3.1.0
dotnet tool install --global clink --version 3.1.0
dotnet new tool-manifest
dotnet tool install --local clink --version 3.1.0
#tool dotnet:?package=clink&version=3.1.0
nuke :add-package clink --version 3.1.0
clink C# Package
This directory contains the production .NET implementation, published as two NuGet packages from a shared source tree:
| Package | Project | Install | Use case |
|---|---|---|---|
clink |
Foundation.Data.Doublets.Cli/ |
dotnet tool install --global clink |
Run the CLI without writing any C#. |
Foundation.Data.Doublets.Cli |
Foundation.Data.Doublets.Cli.Library/ |
dotnet add package Foundation.Data.Doublets.Cli |
Embed the parser, query processors, decorators, named/pinned types, persistent transformation trigger decorator, and LiNo I/O in another .NET project. |
The CLI csproj only contains Program.cs plus the System.CommandLine
wiring; every reusable type lives in the library project so external apps
can recreate or extend the CLI without re-implementing any of the internals.
Install
dotnet tool install --global clink
Update an existing installation:
dotnet tool update --global clink
To consume the library inside another .NET project:
dotnet add package Foundation.Data.Doublets.Cli
API documentation is generated by DocFX from the library's XML doc
comments and is published to GitHub Pages alongside the Rust rustdoc
site by .github/workflows/docs.yml.
Use
clink '() ((1 1))' --changes --after
The CLI exposes the complete command surface, including persistent
transformation triggers with --always, --once, --never, --triggers,
--triggers-file, and --embed-triggers. Each option is implemented in
the public library, so other .NET applications can call into the same
processors directly.
Optional Transactions and Version Control
Pass --transactions (or any flag in the family — --transactions-file,
--commit-mode, --retention, --log) to record each Create/Update/Delete
as a reversible transition in a sidecar doublets store. Pass --vc
(or --vc-file, --branch, --branch-from, --checkout, --tag,
--list-branches, --list-tags) to add a version-control layer over the
recorded transitions log:
# Record reversible transitions into data.transitions.links
clink --db data.links --transactions --auto-create-missing-references '() ((1 1))'
clink --db data.links --log
# Branch and tag on top of the transitions log
clink --db data.links --vc --tag v1
clink --db data.links --vc --branch feature --branch-from 1
clink --db data.links --vc --list-branches
BeginTransaction() / Commit() / Rollback() are also exposed on the
library API for explicit batches. End-to-end demo scripts live in
examples/transactions/ and
examples/version-control/.
Use as a library
Foundation.Data.Doublets.Cli.Library is usable as an embedded
transactional store, not only as the code behind clink.
using Foundation.Data.Doublets.Cli;
// `CreateAndUpdate` and `Exists` are extension methods on `ILinks<T>`.
using Platform.Data;
using Platform.Data.Doublets;
// A `ulong`-addressed store; the CLI's own `uint` store is the
// non-generic `TransactionsDecorator`.
using var data = new NamedTypesDecorator<ulong>("db.links");
using var log = new NamedTypesDecorator<ulong>("db.transitions.links");
using var transactions = new TransactionsDecorator<ulong>(data, log);
using (var transaction = transactions.BeginTransaction())
{
transactions.CreateAndUpdate(transactions.Constants.Null, transactions.Constants.Null);
transaction.Commit();
}
A runnable version of this is
examples/embedded-store/csharp
(dotnet run --project examples/embedded-store/csharp).
- Any address type.
TransactionsDecorator<TLinkAddress>works over anyINamedTypesLinks<TLinkAddress>whose address is anIUnsignedNumber<TLinkAddress>; the non-genericTransactionsDecoratorstays behind as theuintspecialisation the CLI uses. The transitions wire format writes addresses in decimal under the invariant culture, so it is identical across address types, and an address that does not fit the target type is rejected rather than silently truncated. - Crash recovery. Recovery runs when the decorator is constructed: committed-but-unapplied transitions are replayed and transitions that were never committed are rolled back, so an abandoned transaction leaves nothing behind after a reopen.
- Multi-process access.
LinksFileLocklocks a<database>.locksidecar, shared for readers and exclusive for writers, with a blockingAcquireand a non-blockingTryAcquire.StorageRevision.Of(path)/revision.HasChanged(path)answer "has anyone else written since I last looked?" without reparsing the database. The lock file path and the shared/exclusive semantics match the Ruststorage::lockmodule, so both implementations can guard the same database.
Develop
dotnet restore
dotnet build --configuration Release
dotnet test --configuration Release
Release automation for this package lives in csharp/scripts/ and uses
changesets from csharp/.changeset/.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.1.0 | 0 | 8/29/2026 |
| 3.0.0 | 0 | 8/29/2026 |
| 2.6.0 | 217 | 8/18/2026 |
| 2.5.0 | 265 | 5/15/2026 |
| 2.4.0 | 992 | 5/12/2026 |
| 2.2.2 | 5,801 | 6/13/2025 |
| 2.2.1 | 5,291 | 6/12/2025 |
| 2.2.0 | 5,324 | 6/12/2025 |
| 2.1.3 | 5,237 | 5/16/2025 |
| 2.1.2 | 5,199 | 4/6/2025 |
| 2.1.1 | 5,196 | 4/6/2025 |
| 2.1.0 | 5,185 | 4/6/2025 |
| 2.0.2 | 5,190 | 4/6/2025 |
| 1.8.0 | 5,141 | 12/21/2024 |
| 1.7.4 | 5,120 | 12/21/2024 |
| 1.7.3 | 5,126 | 12/21/2024 |
| 1.7.1 | 5,113 | 12/21/2024 |
| 1.7.0 | 5,117 | 12/21/2024 |
| 1.6.0 | 5,146 | 12/15/2024 |
| 1.5.0 | 5,128 | 12/15/2024 |