Short, task-shaped walkthroughs — traverse a graph, gate a build, regenerate listings, normalize a file, ship the binary. For the exhaustive surface, see library.md and cli.md.
Load once, then walk edges in either direction. Broken links stay in the graph so you can find every hole in one pass.
using OKF4net; var bundle = Bundle.Load("./my_bundle"); var id = ConceptId.Parse("tables/orders"); // Outgoing — each link knows whether its target exists. foreach (var link in bundle.LinksFrom(id)) Console.WriteLine($"{id} -> {link.Target} (exists: {link.Exists})"); // Incoming — who cites this concept. foreach (var back in bundle.Backlinks(id)) Console.WriteLine($"cited by {back}"); // Every dangling edge in the whole bundle. foreach (var (source, rawTarget) in bundle.BrokenLinks()) Console.WriteLine($"{source} -x {rawTarget}");
okf validate exits non-zero on a non-conformant bundle. The binary is self-contained, so a runner needs no .NET installed — copy the file and run it.
# .github/workflows/knowledge.yml
name: Validate knowledge
on: [push]
jobs:
okf:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./okf validate ./bundles/ga4Prefer to gate from your own tool? The library reports the same result — warnings never fail conformance, only errors do:
var report = BundleValidator.Validate(Bundle.Load("./bundles/ga4")); Environment.Exit(report.IsConformant ? 0 : 1);
After adding or renaming concepts, rewrite every directory listing. The call returns the paths it wrote.
var written = IndexGenerator.RegenerateIndexes("./my_bundle"); foreach (var path in written) Console.WriteLine($"wrote {path}");
Same thing from the shell: okf index ./my_bundle. Supply your own description synthesizer with RegenerateIndexesWith(root, synthesize) when the default summaries aren't enough.
Bundle.LogFiles lists every reserved log.md; ChangeLog.Parse turns one into date-grouped entries.
using OKF4net; foreach (var logPath in bundle.LogFiles) { var log = ChangeLog.Parse(File.ReadAllText(logPath)); foreach (var day in log.Days) Console.WriteLine($"{day.Date}: {day.Entries.Count} entr(y/ies)"); }
Parse and re-serialize to normalize frontmatter and block structure. Unknown keys come out untouched — the ordered mapping is preserved, not projected onto a fixed type.
var doc = OkfDocument.Parse(File.ReadAllText("orders.md")); File.WriteAllText("orders.md", doc.Serialize());
Or in place from the shell: okf fmt orders.md -w.
Build okf as a self-contained, single-file Native AOT executable — nothing to install where it runs.
$ git clone https://github.com/jchable/okf4net
$ dotnet publish src/OKF4net.Cli -c Release # self-contained okf binary→ cli.md — every command and flag · library.md — the full API