Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .claude/skills/release/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name: release
description: Create a graylog-cli release by determining the next git tag, synchronizing Cargo.toml and flake.nix versions, verifying the Nix build, tagging, and pushing the release trigger.
disable-model-invocation: true
argument-hint: '[patch|minor|major|<version>]'
argument-hint: "[patch|minor|major|<version>]"
allowed-tools: Bash, Read, Edit, Write, Grep, Glob
---

Expand All @@ -23,10 +23,10 @@ Use this skill to prepare and publish a `graylog-cli` release. Releases are trig

The release version is duplicated and must be updated in both places:

| File | Field |
| --- | --- |
| File | Field |
| ------------ | --------------------------------- |
| `Cargo.toml` | `[package] version = "<version>"` |
| `flake.nix` | `version = "<version>";` |
| `flake.nix` | `version = "<version>";` |

The git tag must be `v<version>`, for example `v0.1.0`.

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
- uses: actions/checkout@v6
- uses: DeterminateSystems/nix-installer-action@v22
- run: nix flake lock --update-input fenix
- run: nix develop --command cargo clippy --all-targets --locked -- -D warnings
- run: nix develop .#ci --command cargo clippy --all-targets --locked -- -D warnings

test:
name: test
Expand All @@ -38,7 +38,7 @@ jobs:
- uses: actions/checkout@v6
- uses: DeterminateSystems/nix-installer-action@v22
- run: nix flake lock --update-input fenix
- run: nix develop --command cargo test --all --locked
- run: nix develop .#ci --command cargo test --all --locked

deny:
name: cargo deny
Expand All @@ -47,7 +47,7 @@ jobs:
- uses: actions/checkout@v6
- uses: DeterminateSystems/nix-installer-action@v22
- run: nix flake lock --update-input fenix
- run: nix develop --command cargo deny --all-features check
- run: nix develop .#ci --command cargo deny --all-features check

build-linux:
name: build (linux-x86_64)
Expand Down
86 changes: 86 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# PROJECT KNOWLEDGE BASE

**Generated:** 2026-09-15
**Commit:** bc0f758
**Branch:** main

## OVERVIEW

Rust CLI for Graylog (search/aggregate/streams/system). Hexagonal single crate, tokio + clap + reqwest/rustls.

## STRUCTURE

```
graylog-cli/
├── src/main.rs # composition root, updater worker
├── src/lib.rs # pub mods only
├── src/domain/ # config, models, timerange, error
├── src/application/ # service, updater_service, ports/
├── src/infrastructure/ # graylog_client, config_store, updater
├── src/presentation/ # cli (clap), output (json/table)
├── tests/cli_integration.rs
└── benches/
```

## WHERE TO LOOK

| Task | Location | Notes |
| -------------------- | --------------------------------------------------- | ----------------------------------------- |
| CLI commands/flags | `src/presentation/cli.rs` | clap derive, `validate()` + `to_input()` |
| Use-cases | `src/application/service.rs` | `ApplicationService`, 1969 lines |
| HTTP + normalization | `src/infrastructure/graylog_client.rs` | 1847 lines, `X-Requested-By` |
| Config/cache files | `src/infrastructure/config_store.rs` | `~/.config/graylog-cli/config.toml`, 0700 |
| Output/exit codes | `src/presentation/output.rs` | JSON envelope, codes 1-6 |
| Self-update | `src/application/updater_service.rs`, `src/main.rs` | `__self-update-worker`, 24h throttle |
| Release | `.github/workflows/release.yml` | tag `v*` must be on main |

## CODE MAP

| Symbol | Type | Location | Role |
| ------------------------------------------------------ | ------ | -------------------------------- | ------------------------------------------------------------------------- |
| `ApplicationService` | struct | `application/service.rs` | search/aggregate/auth/ping/streams/system/fields |
| `Config/GraylogConfig/UpdaterConfig` | struct | `domain/config.rs` | TOML config, `SecretString` token |
| `CliError/HttpError/ValidationError` | enum | `domain/error.rs` | layered thiserror + exn |
| `ConfigStore/CacheStore/GraylogGateway/UpdaterGateway` | trait | `application/ports/` | DI seams, glob re-export |
| `FileConfigStore` | struct | `infrastructure/config_store.rs` | atomic write, implements both stores |
| `Cli/Commands` | enum | `presentation/cli.rs` | `auth/search/aggregate/count-by-level/streams/system/ping/fields/upgrade` |
| `print_json/print_table/exit_code_for_cli_error` | fn | `presentation/output.rs` | machine contract |

## CONVENTIONS

- Hexagonal: `application` never does I/O directly, only via `ports` traits; adapters in `infrastructure`.
- Errors: `thiserror` layer enums + `exn::Result`; `main()` returns `()`, single `emit_cli_error` prints JSON to stderr.
- Success = JSON on stdout; `--format table` only exception. No prompts, non-interactive.
- Token via `--token` or `GRAYLOG_TOKEN` env (clap `env`). Auto-update via `GRAYLOG_CLI_AUTO_UPDATE` or `[updater]` TOML.
- Edition 2024 (let-chains), `max_width=100`, treefmt via pre-commit. Conventional Commits.

## ANTI-PATTERNS (THIS PROJECT)

- Don't return `Result` from `main` or add `anyhow`; use `exn` + JSON envelope + semantic exit codes.
- Don't I/O in `ApplicationService`; go through `ports`.
- Don't set `target-cpu=native` in `.cargo/config.toml` (breaks cross builds).
- No `unsafe`, no `#[allow]` in `src/`; clippy `-D warnings` in CI.
- Never serialize `GraylogConfig` to stdout (token is plaintext in TOML serde).

## UNIQUE STYLES

- `lib.rs` is 4 lines; `main.rs` wires `Arc<FileConfigStore>` twice (config + cache).
- Fields cache is per profile (`fields-<profile>.json` next to `config.toml`) with TTL 300s.
- Release patches `Cargo.toml` version from tag; `publish=false`, ships binaries only.

## COMMANDS

```bash
nix develop --command cargo test --all --locked
nix develop --command cargo clippy --all-targets --locked -- -D warnings
nix develop --command cargo deny --all-features check
cargo bench # timerange_parsing, json_normalization
nix build
nix build .#graylog-cli-windows
```

## NOTES

- Two hotspots hold ~52% LOC: `service.rs`, `graylog_client.rs`. `cli.rs` (852) holds full command tree.
- `publish=false`; tags `v*` must point at `main` (verified in release.yml).
- `dirs::config_dir()/graylog-cli/` holds `config.toml` + `<key>.json` caches.
Loading