Files
wwtools/aalogcli/AGENTS.md
Joseph Doherty 32f26272ae Initial commit: Wonderware / System Platform tools and reference
Five tools under one repo, all docs organized per DOCS-GUIDE.md:

- aalogcli: .NET 4.8 / x86 CliFx CLI for reading System Platform binary
  logs (*.aaLGX) for LLM debugging, built on aaOpenSource/aaLog. Commands:
  last, tail, range, unread, fields. Stable JSON envelope under --llm-json.
  Build template under lib/build/ for rebuilding aaLogReader.dll.

- aot: ArchestrA Object Toolkit 2014 v4.0 reference material. Dev guide
  (Markdown converted from CHM), API reference for the ArchestrA.Toolkit
  namespace, and the Monitor / Watchdog VS sample solutions.

- graccesscli: .NET 4.8 / x86 CliFx CLI that automates Galaxy
  configuration via the ArchestrA GRAccess COM interop. Includes session
  daemon, IPC protocol, and llm-json envelope contract.

- grdb: SQL/DDL exploration of the Galaxy Repository database. DDL
  captures, reusable queries, hierarchy / contained-name <-> tag-name
  translation notes.

- histdb: LLM-oriented reference for AVEVA Historian retrieval. INSQL
  linked-server, extension tables, every wwXxx time-domain extension,
  every retrieval mode, alarm/event SQL recipes, REST API. Distilled
  from the 243-page Historian Retrieval Guide.

Root contains:
- CLAUDE.md: thin index pointing into each tool's README.
- DOCS-GUIDE.md: doctrine for organizing docs for LLM consumption.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 18:22:20 -04:00

5.2 KiB

AGENTS.md

Guidance for coding agents working in the aalogcli folder.

Project Snapshot

This folder contains aalogcli (assembly name aalog), a .NET Framework 4.8 / x86 CliFx-based CLI for reading AVEVA / Wonderware System Platform binary log files (*.aaLGX). It wraps the third-party reader library aaOpenSource/aaLog and exposes it as last, tail, range, unread, and fields commands tailored for LLM-driven debugging (stable JSON envelope, bounded payloads, post-fetch filters).

For end-to-end command reference and examples, read docs/usage.md. For the JSON shape of an emitted record, read docs/fields.md. For the upstream reader's API (used by LogReaderFactory.cs and the commands), see the aaLog README.

Key Documentation

All paths are relative to this aalogcli/ folder.

  • README.md — tool entry point, hard constraints, build instructions.
  • docs/usage.md — every command, every option, with worked examples for the LLM-JSON envelope.
  • docs/fields.mdLogRecordDto field reference; the canonical shape of records in --llm-json output.

Repository Layout

aalogcli/
  AaLog.Cli.slnx
  lib/aaLogReader.dll          (provisioned out-of-band — see README)
  src/AaLog.Cli/
    AaLog.Cli.csproj
    Program.cs
    LogReaderFactory.cs
    Commands/
      CommonOptions.cs         (ReadCommandBase — shared options)
      LastCommand.cs           (`last`  — last N records)
      TailCommand.cs           (`tail`  — last N minutes)
      RangeCommand.cs          (`range` — explicit start/end)
      UnreadCommand.cs         (`unread`— incremental, cache-backed)
      FieldsCommand.cs         (`fields`— field reference printout)
    Output/
      LogRecordDto.cs          (LLM-friendly subset of aaLogReader.LogRecord)
      OutputWriter.cs          (human single-line + llm-json envelope)
    Filtering/
      RecordFilter.cs          (substring / regex over Component, Level, Message)
    IsExternalInit.cs          (C# 9 `init` polyfill for net48)

Build And Test

Run commands from this aalogcli folder unless noted otherwise.

dotnet build src/AaLog.Cli/AaLog.Cli.csproj -p:Platform=x86 -c Release
dotnet run --project src/AaLog.Cli/AaLog.Cli.csproj -- <args>

There is no test project at present. If you add one, mirror graccesscli's convention: tests/AaLog.Cli.Tests/AaLog.Cli.Tests.csproj, net48 / x86, xunit + Shouldly.

Implementation Rules

  • Keep the CLI targeting net48 and x86. The upstream aaLogReader is net40 — net48 loads it cleanly, .NET 10 / x64 will not.
  • Do not add a [STAThread] apartment requirement. Unlike graccesscli, aaLogReader is plain managed file I/O and runs fine on any thread.
  • Construct readers through LogReaderFactory.Open so every command honors --log-dir the same way.
  • Always wrap the reader in using — it implements IDisposable and holds a FileStream.
  • Treat the upstream library as authoritative for log decoding. Do not reimplement aaLGX parsing in this CLI.
  • Filtering is client-side, after the library returns records. Do not push filter strings into OptionsStruct.LogRecordPostFilters from the CLI layer — surface stays flatter that way.
  • Every read command must inherit ReadCommandBase so --log-dir / --component / --level / --message / --regex / --llm-json stay consistent.
  • --llm-json envelope shape is { query: {...}, count: N, records: [LogRecordDto, ...] }. Preserve the envelope contract — agents may parse it positionally.
  • LogRecordDto is the JSON contract. Adding a field is a non-breaking change; renaming or removing one is breaking — bump the docs in the same commit and call it out.
  • C# language version is 9.0. init is supported through IsExternalInit.cs; do not use the required keyword.
  • Use CliFx command patterns: [Command], [CommandOption], classes implement ICommand.

Output Contracts

Mode Trigger Shape
Human default One line per record: [localTs] [level] component (process#pid/tid) | message
LLM-JSON --llm-json { "query": {...}, "count": N, "records": [LogRecordDto, ...] }

The query object echoes the invocation parameters so an agent reading the JSON can confirm which window it actually got. log_dir in the query is the resolved directory (post---log-dir override), so it doubles as a sanity check.

Adding A New Command

  1. Add Commands/<Name>Command.cs inheriting ReadCommandBase and implementing ICommand.
  2. If it introduces a new query verb (e.g. since-message-number), wrap the corresponding aaLogReader method in LogReaderFactory or inline; document the verb in docs/usage.md.
  3. Add a row in README.md and docs/usage.md. Do not modify ../CLAUDE.md — the root index points at this README and that is sufficient.
  4. Keep --llm-json envelope semantics identical across commands (query, count, records).