32f26272ae
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>
84 lines
5.2 KiB
Markdown
84 lines
5.2 KiB
Markdown
# 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`](https://github.com/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`](docs/usage.md). For the JSON shape of an emitted record, read [`docs/fields.md`](docs/fields.md). For the upstream reader's API (used by [`LogReaderFactory.cs`](src/AaLog.Cli/LogReaderFactory.cs) and the commands), see the [aaLog README](https://github.com/aaOpenSource/aaLog).
|
|
|
|
## Key Documentation
|
|
|
|
All paths are relative to this `aalogcli/` folder.
|
|
|
|
- [`README.md`](README.md) — tool entry point, hard constraints, build instructions.
|
|
- [`docs/usage.md`](docs/usage.md) — every command, every option, with worked examples for the LLM-JSON envelope.
|
|
- [`docs/fields.md`](docs/fields.md) — `LogRecordDto` field reference; the canonical shape of records in `--llm-json` output.
|
|
|
|
## Repository Layout
|
|
|
|
```text
|
|
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.
|
|
|
|
```powershell
|
|
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`](src/AaLog.Cli/LogReaderFactory.cs) 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`](src/AaLog.Cli/Commands/CommonOptions.cs) 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`](docs/usage.md).
|
|
3. Add a row in [`README.md`](README.md) and [`docs/usage.md`](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`).
|