wavepeek 1.0.1

Command-line tool for RTL waveform inspection with deterministic machine-friendly output.
Documentation
# Optional GitHub Authentication

The local devcontainer supports optional GitHub authentication for maintainer work. The default host setup uses an empty env file, and normal build/test flows do not require a token. If the host already has `~/.config/wavepeek-dev/github.env` pointing at a maintainer token, newly created containers will receive that token.

## Authentication Model

The devcontainer reads one host-side env file when the container is created:

```text
~/.config/wavepeek-dev/github.env
```

`.devcontainer/initialize.sh` creates an empty default outside the repository. `.devcontainer/devcontainer.json` passes that file to Docker with `--env-file`. `.devcontainer/setup-github-auth.sh` runs inside the container and configures repo-local GitHub access only when `GH_TOKEN` or `GITHUB_TOKEN` is present.

The devcontainer does not mount host `~/.config/gh`. GitHub CLI uses `GH_TOKEN` or `GITHUB_TOKEN` from the container environment instead.

The container sets:

```text
WAVEPEEK_UPSTREAM_REPO=kleverhq/wavepeek
GH_PROMPT_DISABLED=1
```

It intentionally does not set `GH_REPO`. Scripts that target the upstream repository should pass it explicitly:

```bash
gh pr list -R "$WAVEPEEK_UPSTREAM_REPO"
gh issue list -R "$WAVEPEEK_UPSTREAM_REPO"
gh run list -R "$WAVEPEEK_UPSTREAM_REPO"
```

## Host Env Files

Expected host-side layout:

```text
~/.config/wavepeek-dev/github.empty.env
~/.config/wavepeek-dev/github.maintainer.env
~/.config/wavepeek-dev/github.env -> github.empty.env or github.maintainer.env
```

`github.empty.env` is created automatically and should stay empty. `github.env` is the active file Docker reads at container creation time. Maintainers can point it at `github.maintainer.env` for trusted work.

Docker does not reread `--env-file` for an existing container. After changing `github.env`, recreate or rebuild the devcontainer. Attaching to an existing container keeps the old environment.

## Maintainer Setup

Create a GitHub token limited to `kleverhq/wavepeek` with only the permissions needed for the task.

To create or activate maintainer credentials, run this from the repository root on the host:

```bash
bash tools/repo/setup_github_env.sh
```

The helper prompts for the token without echoing it, then writes:

```text
~/.config/wavepeek-dev/github.empty.env
~/.config/wavepeek-dev/github.maintainer.env
~/.config/wavepeek-dev/github.env -> github.maintainer.env
```

The helper rejects positional arguments so the token is not exposed through shell history or process argv by the documented command. For non-interactive use, pipe exactly one token line into the script:

```bash
printf '%s\n' "$TOKEN" | bash tools/repo/setup_github_env.sh
```

The helper tolerates unrelated wavepeek-managed entries in `~/.config/wavepeek-dev`, such as agent state placeholders and `verdi`. It also tolerates the default empty GitHub files created by `.devcontainer/initialize.sh`. It refuses to overwrite an existing `github.maintainer.env`, a non-empty or non-file `github.empty.env`, or an active `github.env` that is not the default `github.empty.env` symlink. Edit the files manually in those cases, because overwriting token state by surprise is the sort of convenience that later appears in incident reports.

Manual `github.maintainer.env` content:

```text
GH_TOKEN=<github-token>
GITHUB_TOKEN=<github-token>
WAVEPEEK_GITHUB_ROLE=maintainer
```

After setup, recreate or rebuild the devcontainer. Then verify inside the container:

```bash
gh repo view "$WAVEPEEK_UPSTREAM_REPO"
gh pr list -R "$WAVEPEEK_UPSTREAM_REPO" --limit 5
gh issue list -R "$WAVEPEEK_UPSTREAM_REPO" --limit 5
```

Git HTTPS operations against `https://github.com/kleverhq/wavepeek.git` use a repo-local, path-specific credential helper. The helper stores shell logic in `.git/config`, not the token value, and only returns credentials for the configured upstream repository path. It also resets broader inherited GitHub credential helpers for that upstream path so a plain `git push origin <branch>` works even when an editor or global helper has stale GitHub credentials cached.

## External PR Review

Treat code from fork PRs as untrusted. Switching `github.env` to the empty file removes the token from newly created containers, but it does not protect a readable token file on the host from PR-controlled `initializeCommand` code.

Before opening a devcontainer from an untrusted PR checkout, make the maintainer token unavailable to the host process that will run the devcontainer configuration. Use one of these approaches:

- remove the token-bearing env file and recreate it later;
- use a separate host account, VM, or codespace without the token file;
- keep the token in a password manager and generate `github.env` only for trusted work;
- create the container from trusted base-branch devcontainer config, then check out the PR inside that container.

Also switch the active env file to the empty default:

```bash
ln -sf github.empty.env ~/.config/wavepeek-dev/github.env
```

Then recreate or rebuild the devcontainer. Do not attach to an existing container that may still have the old token environment.

Verify inside the new container:

```bash
test -z "${GH_TOKEN-}"
test -z "${GITHUB_TOKEN-}"
test ! -e /home/ubuntu/.config/gh/hosts.yml
```

## Fork Contributor Flow

External contributors do not need a `kleverhq/wavepeek` token for normal development.

Recommended remotes for fork contributors:

```text
origin   = git@github.com:<contributor-login>/wavepeek.git
upstream = https://github.com/kleverhq/wavepeek.git
```

`.devcontainer/setup-github-auth.sh` adds or updates `upstream` when `origin` is not the upstream repository. It does not rewrite `origin`.

Typical flow:

```bash
git checkout -b my-change
# edit, build, test
git push -u origin my-change
```

A pull request can be opened through the GitHub web UI. Contributors who already have GitHub CLI authentication may use:

```bash
gh pr create \
  -R kleverhq/wavepeek \
  --head "<contributor-login>:my-change" \
  --base main \
  --fill
```

## Verification

Syntax checks after changing this workflow:

```bash
bash -n .devcontainer/initialize.sh
bash -n .devcontainer/setup-github-auth.sh
bash -n tools/repo/setup_github_env.sh
python3 -m json.tool .devcontainer/devcontainer.json >/dev/null
```

No-token container checks:

```bash
test -z "${GH_TOKEN-}"
test -z "${GITHUB_TOKEN-}"
test ! -e /home/ubuntu/.config/gh/hosts.yml
```

For fork checkouts where `origin` is not `kleverhq/wavepeek`, also verify the upstream remote:

```bash
git remote get-url upstream
```

Maintainer-token checks:

```bash
gh repo view "$WAVEPEEK_UPSTREAM_REPO"
gh pr list -R "$WAVEPEEK_UPSTREAM_REPO" --limit 5
gh issue list -R "$WAVEPEEK_UPSTREAM_REPO" --limit 5
```

Secret leakage checks:

```bash
git remote -v
git config --local --list --show-origin | grep -Ei 'github_pat|ghp_' && exit 1 || true
git config --global --list --show-origin | grep -Ei 'github_pat|ghp_' && exit 1 || true
```

## Troubleshooting

If `gh repo view "$WAVEPEEK_UPSTREAM_REPO"` fails with a token present, check that the token has access to `kleverhq/wavepeek` and the permissions needed for the command.

If switching between maintainer and empty credentials appears to have no effect, recreate or rebuild the devcontainer. Docker does not reread `--env-file` for an existing container.

If `upstream` points somewhere unexpected, inspect `origin` first:

```bash
git remote -v
```

The setup script only adds or updates `upstream` when `origin` is not `kleverhq/wavepeek`; it never rewrites `origin`.

If `git push origin <branch>` still tries a stale editor or global GitHub credential, rerun the in-container setup step and inspect the repo-local helper entries:

```bash
bash .devcontainer/setup-github-auth.sh
git config --local --get-all credential.https://github.com/kleverhq/wavepeek.helper
git config --local --get-all credential.https://github.com/kleverhq/wavepeek.git.helper
```

Each upstream path should have an empty first helper entry followed by `!wavepeek_github_credential_helper...`. The empty entry is intentional; it tells Git to ignore broader helpers for that exact upstream path.