Repository navigation
Conversation
New subcommand writes ~/.config/tau/config.json as JSONC: it scans the provider table's env_keys (plus TAU_API_KEY), selects the first provider with a detected key (or an explicit --provider), and emits a commented starter that names every provider's env vars -- never copying secret values. Refuses to overwrite an existing file unless --force; --stdout previews without writing. configfile.load now strips // and /* */ comments before parsing so the scaffolded file (and hand-commented configs) load cleanly; string-aware scanning keeps "//" inside values (e.g. URLs) intact. Also wires help/guide entries, bash/zsh completions, an offline smoke group, and fixes a stray literal backslash before the Examples header in --help output. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
docs/troubleshooting.md maps each user-visible error message (by exit
code and envelope type) to its cause and fix. To make the doc
discoverable, every {"err":...} envelope now carries a "docs" field
pointing at the published URL — the constant lives in version.zig as the
single source of truth. README's Troubleshooting section links the doc
and the embedded guide's see_also lists it.
Unit-test run() end-to-end against a hermetic tmp HOME (same convention as configfile.zig's TestHome): fresh write produces a commented config that loads without warning, existing configs are refused without --force (contents untouched), --force regenerates the scaffold, --stdout writes nothing, and a missing HOME exits 110.
…134) Pin the user-visible error contract so DX regressions are caught in CI: - golden test asserting formatErrorJson output byte-for-byte, including the "docs" link to the troubleshooting FAQ - source scan asserting every hand-rolled {"err":...} literal in main/agent/acp/fleet/helpers keeps a "docs" field - doc tests asserting docs/troubleshooting.md indexes every exit code, embeds its own canonical URL, and is linked from the README
Extend shell completion support beyond bash/zsh: - completions/tau.fish — fish completion with subcommand-aware context helpers, per-candidate descriptions, and @file injection that strips the sigil, delegates to the builtin file completer, and re-adds '@' - completions/tau.ps1 — PowerShell Register-ArgumentCompleter script (PS 5.1+/pwsh 7+) with tooltip descriptions, quoted '@file' handling (bare '@x' is splat syntax in PowerShell), and a Get-ChildItem fallback when CompletionCompleters is unavailable - completions/tau.bash, completions/_tau — parity fixes: add the missing 'guide' subcommand and 'calculator' tool, and offer fleet flags before the sub-subcommand (valid per args.zig ordering) - completions/README.md — fish/pwsh install docs, file/shell matrix, the PowerShell @file quoting caveat - scripts/smoke.sh — new offline 'completions' group asserting every --help-json flag, subcommand, and enum value appears in all four completion files (drift guard) - README.md + CONTRIBUTING.md — point to completions/ Verified: fish 3.7 and pwsh 7.4 exercised end-to-end via complete --do-complete / TabExpansion2; bash tested via COMP_WORDS simulation; zsh via zpty. 274/274 zig tests, 13/13 completions smoke checks, no regressions in help/flags/fleet-flags groups. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…able install.sh Adopters shouldn't need a Zig toolchain to try tau. Push a v* tag and the release workflow cross-compiles all four targets (linux/macos x86_64+aarch64) from a single Linux runner, publishes tau-<os>-<arch>.tar.gz assets plus SHA256SUMS.txt, and creates the GitHub release via gh CLI (no third-party actions beyond checkout/artifact upload). A guard step fails the run when the tag doesn't match src/version.zig; suffixed tags publish as pre-releases. workflow_dispatch runs build-only for validation. install.sh (POSIX sh) detects OS/arch, resolves the latest or --version-pinned asset URL, verifies the checksum when sha256sum/shasum is available, and installs to ~/.local/bin. --dry-run and TAU_OS/TAU_ARCH overrides make the platform mapping testable offline, exercised by a new 27-check 'release' smoke group that also drift-guards the workflow file. Verified: all 4 targets cross-compile with zig 0.16.0; 27/27 release smoke checks green; README + CHANGELOG updated.
Adds a smoke job to release.yml that runs after build and gates release: each dist tarball is staged behind a local HTTP stand-in for the GitHub releases URL, installed end-to-end through install.sh on the matching runner (ubuntu-latest, ubuntu-24.04-arm, macos-15-intel, macos-latest), and verified with tau --version/--help. Covers all four shipped assets. install.sh gains a documented TAU_BASE_URL env override so the installer can be pointed at any base URL exposing the releases layout — this is what the smoke job (and local smoke tests via file://) use. Fixes a latent checksum-verification bug the e2e check surfaced: the release job generated SHA256SUMS.txt with ./-prefixed filenames while install.sh greps " <asset>$" (space before the name), so no line ever matched and every real install would abort. The workflow now emits clean filenames and the installer grep tolerates an optional ./ prefix. Verified: release smoke group 49/49 green, including a full offline file:// install (download → checksum → extract → install → version/help) and a checksum-mismatch rejection. release.yml parses as valid YAML.
… mago/task-151
CI adopters can now install tau with a single `uses: javimosch/tau@<ref>` line. The composite action shells out to the repo's own install.sh via $GITHUB_ACTION_PATH (so installer version matches the action ref), exposes version/install-dir/base-url inputs mapped to the installer's TAU_* env overrides, appends the install dir to $GITHUB_PATH, and surfaces tau-path + version step outputs. release.yml gains a smoke-action job that stages the linux-x86_64 tarball behind a local HTTP stand-in and runs `uses: ./` end-to-end (download → checksum → install → outputs/PATH checks), gating the release publish on the action working as advertised. scripts/smoke.sh's release group pins the action surface: composite type, install.sh invocation, all three inputs and their env mapping, GITHUB_PATH/GITHUB_OUTPUT wiring, outputs, and a conditional YAML parse. Verified: release smoke group 69/69; action run block exercised offline against a staged file:// release tree (install + outputs correct); action.yml and release.yml parse as YAML. Stacked on mago/task-147 (install.sh + release smoke job, PRs #146/#150) — this PR includes those commits until they merge. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Validates the whole setup chain in one JSON report on stdout: config file parse (missing vs invalid vs unknown provider), provider/model/endpoint resolution, API key provenance (source only — never the key), curl on PATH, endpoint reachability (~5s probe), and an optional --deep authenticated probe (max_tokens=1). --offline marks network checks "skip". Exit 0 when no check fails, 1 otherwise; unknown args exit 80. An unknown provider is carried into the report as a failed provider_resolution check instead of exiting 80, so doctor stays useful exactly when setup is broken. Supporting changes: Config gains doctor_offline/doctor_deep/ doctor_bad_provider plus config_path (set by configfile.load when a file is read); resolveApiKeyInfo exposes key provenance (resolveApiKey now delegates to it — same precedence contract, existing tests unchanged). 9 new unit tests in doctor.zig, 4 in args.zig (288/288 green); new 'doctor' smoke group (33 offline checks); help_text Diagnostics section; AGENTS.md cheatsheet + file map; README/docs/configuration.md/CHANGELOG pointers. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… mago/task-161
…um chain in release.yml install.sh previously warned-and-continued when SHA256SUMS.txt was unreachable or no sha256sum/shasum existed — a silent trust path for tampered or corrupted binaries. Verification is now mandatory: the install aborts when the manifest can't be fetched, the asset isn't listed in it, no checksum tool is available, or the digest mismatches. TAU_SKIP_CHECKSUM=1 is a documented opt-out for air-gapped mirrors. release.yml closes the loop end-to-end: the build job emits a per-asset .tar.gz.sha256 alongside each tarball, both smoke jobs verify it against the downloaded artifact before staging, and the release job re-checks SHA256SUMS.txt before publishing so a malformed manifest can never ship (it would brick every install under fail-closed semantics). Smoke release group grows 49 -> 83 checks: drift guards for the new workflow steps plus e2e cases for manifest-miss, unlisted-asset, and the skip-checksum bypass. README + CHANGELOG updated.
…codes Adds the coverage issue #165 asks for on top of the `tau doctor` implementation (PR #160 / mago/task-127): - zig: checkConfigFile now exercised through real file I/O via a throwaway HOME (missing file, valid file, invalid JSON, unreadable/dir-as-file), checkEndpoint and checkAuthProbe failure paths pinned against a refused local port, keyHint/providerListHint contents, ok:true report shape with warnings, and curlHttpCode's spawn-failure null. - smoke: doctor group 33 -> 63 checks — curl missing from PATH cascade (--deep so both network checks report the curl gate), warn-doesn't-fail exit 0, positional-arg exit 80 with stderr message, and a local python stub server driving endpoint_reachable (401 counts as reachable) plus --deep auth_probe for HTTP 200/401/429 including a key-material leak assertion. - CHANGELOG: Tests section entry for #165. Verified: zig build test 297/297, smoke doctor group 63/63.
--debug already streamed [DEBUG] lines to stderr; it now also mirrors them
to ~/.config/tau/debug/<UTC-timestamp>-<suffix>.log (TAU_DEBUG_LOG overrides)
so users can attach the file to bug reports. New src/debuglog.zig owns the
log: it masks the resolved API key plus every other configured/env key,
Bearer tokens, api_key-style JSON fields, and *_KEY=/_TOKEN= env-style
assignments (***REDACTED***); stderr keeps the raw output. The file is
created owner-only (0600) with a provenance header (version, provider,
model, endpoint, key_resolved) and each entry is capped at 8 KiB.
Error envelopes gain an optional "debug_log" field linking the active log
(formatErrorJson + the /goal-session literal emitter — the only literal on
the .run path where a log can exist), and startup emits {"debug_log":...}
on stderr. Failure to create the file degrades to a warn envelope; the run
continues on stderr-only debug output.
Also makes the help text's "perf stats" claim real: a [DEBUG] perf line
(tokens_out, elapsed_ms, exit_code) is emitted once per run.
Stacked on mago/task-130 (PR #131) — both touch the err envelope format;
stacking keeps the docs field consistent.
Closes #167
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ediation hints
Every {"err":...} envelope now carries code, type, message, recoverable,
a remediation hint, and the docs link — emitted from one shared formatter
(src/errors.zig) instead of six hand-rolled literals across main/agent/acp/
fleet/helpers.
- errors.zig: canonical Spec registry (codes 1/80/82/105/106/110/111),
specFor() lookup, format()/printErr()/printOut() emitters that splice in
debuglog's debug_log field, and an OOM fallback that keeps the shape.
- Codes and wire `type` tags are documented as stable (never renumbered or
renamed) in a new "Stable error catalog" table in docs/troubleshooting.md.
- Auth failures keep their dynamic hint (names the provider env var); all
other codes fall back to the catalog hint.
- Snapshot tests pin every catalog entry byte-for-byte; sync tests assert
the catalog covers docs/troubleshooting.md and --help-json exit_codes;
the literal-emitter source scan now also requires the hint field.
- Smoke: envelope assertions now check recoverable/hint/docs (82-path gated
on has_key since fleet's auth check fires first in keyless envs).
Stacked on mago/task-167 (PR #168) — it owns the current envelope shape
(docs + debug_log fields). docs/integration.md (PR #145) already declares
new fields non-breaking; its "minimal {code,message} envelope" line goes
stale once both land and should be updated there.
Closes #171
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…stable tags Adds a `homebrew` job to the release workflow that regenerates Formula/tau.rb from the published SHA256SUMS.txt manifest (new scripts/generate-homebrew-formula.sh, runnable standalone) and pushes it to javimosch/homebrew-tap via the contents API, so macOS/Linux users can `brew install javimosch/tap/tau` and track releases with `brew upgrade`. Pre-release tags (v*-*) are skipped so the tap only tracks stable versions, and the publish step warns + skips when the HOMEBREW_TAP_TOKEN secret is absent rather than failing the release. Docs: README gets a Homebrew install option, release notes mention brew, CHANGELOG + AGENTS.md file map updated. Smoke release group grows to 118 checks covering the generator (render, v-strip, fail-closed paths) and workflow drift guards. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- New docs/providers.md: per-provider credential setup (env vars, config keys map, endpoints, default models), the 6-level key-resolution chain, and exit-106 auth troubleshooting (missing key, silent keyless exit, rejected key, shadowed TAU_API_KEY, TAU_ENDPOINT auth mismatches). - errors.zig: Spec gains a `docs` field (default: troubleshooting URL) and Opts a docs override; the auth_failed spec points envelopes at providers.md so every code-106 error links the credential guide. - version.zig: providers_doc_url constant next to troubleshooting_doc_url. - Cross-links: troubleshooting.md (example envelope, catalog docs column, auth section), README quickstart + troubleshooting table, configuration.md Providers section, `tau guide` see_also. - Pins: golden snapshot updated; new tests pin the 106 -> providers.md link and that providers.md documents every provider's name, env keys, endpoint, and default model; smoke dry-run group gains a keyless fleet-run envelope check.
…Windows smoke Adds the Windows install path end-to-end: - release.yml: new x86_64-windows-gnu build target shipping tau-windows-x86_64.zip (Windows convention); SHA256SUMS.txt now covers .zip assets; new smoke-windows job installs the zip through install.ps1 on a native windows-latest runner (file:// TAU_BASE_URL staging) and verifies tau.exe --version/--help before the release can publish. - install.ps1: mirrors the install.sh contract — -Version/-Dir/-DryRun/ -Help (both -name and --name forms, manual $args parse since pwsh does not bind --switches), TAU_VERSION/TAU_INSTALL_DIR/TAU_ARCH/TAU_BASE_URL/ TAU_SKIP_CHECKSUM overrides, fail-closed Get-FileHash SHA256 verification, Expand-Archive install to %LOCALAPPDATA%\Programs\tau with a user-PATH note. throw/return instead of exit so irm|iex installs don't kill the caller's shell; file:// URLs resolve via System.Uri so the staging trick works on every pwsh host. - scripts/generate-winget-manifest.sh: renders the three-file microsoft/winget-pkgs manifest (version/installer/defaultLocale) from the published checksums; the winget job validates it, uploads it as a workflow artifact, and auto-submits via wingetcreate when WINGET_PKGS_TOKEN is configured (warn-and-skip otherwise). - scripts/generate-scoop-manifest.sh: renders bucket/tau.json for javimosch/scoop-bucket; the scoop job publishes via gh api contents PUT behind SCOOP_BUCKET_TOKEN, warn-and-skip while the token is unset or the bucket repo does not exist. - smoke.sh release group: +install.ps1 surface checks (pwsh-gated), workflow drift guards for the new jobs, generator contract tests, and a file:// install.ps1 e2e exercising the full fail-closed checksum ladder. - README quickstart + release notes + CHANGELOG document the Windows path. Stacked on mago/task-175 (the release chain this extends). Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…tor)
`tau setup` runs the full first-run flow as one NDJSON transcript:
scaffolds ~/.config/tau/config.json (init semantics — keeps an existing
file instead of failing), installs shell completions for the $SHELL-
detected shell (--shell bash|zsh|fish|pwsh|all overrides), and embeds the
`tau doctor` health report, ending with a {"step":"setup","ok":...}
verdict. Exit 0 when every step is ok/skipped, 1 on any failure.
Idempotent: rc/profile edits carry a "# tau completions" marker so
re-runs don't duplicate lines.
- build.zig generates a `completions` module embedding completions/*
via addWriteFiles, so `tau setup` installs scripts without a checkout
- doctor.zig: split collectReport() out of run() for reuse; fix
config_file check to strip JSONC comments (init scaffolds parse ok now)
- --provider/--model/--api-key/--offline/--deep pass through to the
doctor step; unknown providers ride in as a failed check (doctor
convention) while init falls back to detection
- completions: add init/doctor/setup coverage to bash, zsh, fish, pwsh
- 6 new unit tests + 41-check smoke group; docs: README, AGENTS.md,
CHANGELOG, completions/README, docs/configuration.md
Closes #181
…ind confirmation
`tau doctor --fix` plans and applies remediations for fixable check
outcomes: scaffold a missing config (init semantics, creates ~/.config/tau),
move an unparseable config to config.json.bak and re-scaffold, tighten POSIX
permission bits (0700 dir / 0600 file — the file can hold API keys), and
install/refresh shell completions. Every fix requires confirmation: --yes
(also -y, implies --fix) applies all non-interactively, a TTY stdin gets a
per-fix y/N prompt on stderr, and anything else is reported as skipped. The
emitted report gains a "fixes" array ({id,check,status,detail}) and reflects
the post-fix state when anything was applied; the exit code follows the
final report.
Two new always-on diagnostics back the remediations: config_permissions
(warn on group/other access, POSIX-only) and shell_completions (warn on
missing/outdated scripts or absent rc hooks for the detected/--shell shell).
Also exports the completion install helpers in setup.zig (installCompletion,
completionState, resolveShells, rc/script accessors) so doctor and setup
share one code path, and completes the new flags in all four shell scripts.
Verified: 324/324 zig tests (8 new covering planning, confirmation, every
fix kind, and round-trips), 84/84 doctor smoke checks including the new
--fix sections (skip-without-confirm, apply-with---yes, .bak restore),
setup/init/completions groups green, x86_64-windows-gnu cross-compile.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…trix Adds .github/workflows/ci.yml which runs `zig build test` and both offline smoke suites on a native runner for each released platform (linux x86_64/aarch64, macos x86_64/aarch64, windows x86_64) on PRs, master pushes, and v* tags — so platform regressions fail before a release is cut. `workflow_call` is exposed so the release workflow can gate on the matrix. Portability fixes to make that matrix green: - args.zig: parse() now takes a plain argv slice instead of std.process.Args, whose POSIX-only `.vector` field broke `zig build test` compilation for windows-gnu. main.zig materializes the platform argv (WTF-16 on Windows, UTF-8 on POSIX) into a UTF-8 slice itself. - smoke.sh: the acp group now pins both documented daemon contracts — exit 0 + running:false on POSIX, exit 111 err envelope on Windows — instead of failing on the Windows leg. - smoke.sh + smoke-features.sh: pass --api-key fake to checks exercising post-auth validation (fleet run without --goal, /goal without --session), so they are deterministic in keyless CI environments — key resolution precedes those checks and would exit 106 first. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
--json replaces the single-object report with line-delimited events matching
the documented stream contract: {"check":{...},"done":false} per check as it
finishes, {"fix":{...},"done":false} per remediation under --fix, and a
terminal {"ok","version","summary","fixes"?,"done":true} verdict. A check
re-diagnosed after an applied fix re-emits with its post-fix status. Exit
codes, the default report shape, and `tau setup`'s embedded report are
unchanged.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
# Conflicts: # scripts/smoke.sh
Bakes build provenance into the binary via a build.zig options module: git commit (short hash, "-dirty" on uncommitted changes, "unknown" for tarball builds), UTC build date (honors SOURCE_DATE_EPOCH so release binaries stay byte-reproducible), arch-os-abi target triple, and the zig compiler version — all exposed from version.zig's new `build` struct. Surfaced in three places so a bug report can pin down the exact binary: - `tau version --verbose` prints a JSON object (key:value lines under --mode text); bare `tau version` stays identical to -v/--version - `tau doctor` report and --json terminal verdict carry a "build" object - the --debug log header gains a `# build:` line via debuglog.writeHeader Includes version-subcommand args tests, version.zig formatter tests, doctor build-field pins, a 16-check `version` smoke group, completions for all four shells, and AGENTS.md/CHANGELOG updates. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… bundle Stacked on mago/task-204 (doctor --json/--fix chain + version.build + debuglog). `tau doctor --report` prints a Markdown bundle for pasting into a GitHub issue: verdict line, build metadata table (version/commit/target/build date/zig), the checks table, a Fixes table when --fix ran, effective settings (provider/model/endpoint/context_window + key source — never the key), and the config file verbatim in a fenced jsonc block. The config dump is passed through debuglog.redactAlloc with every credential source collected (resolved key, --api-key, config api_key + keys.*, TAU_API_KEY, all provider env vars, builtins), so key material can never leak into the report. Paths stay visible, matching the --debug log convention. --report + --json is rejected at parse time with exit 80 (mutually exclusive). Exit codes and the default JSON report are unchanged. debuglog.zig: registerSecrets refactored onto a new pub collectSecrets so the same source enumeration serves both the --debug log and --report. Also: help_text + guide commands row, all four completion scripts + completions README, troubleshooting.md diagnostic-toolkit row, unit tests (formatReportMarkdown shape/redaction, appendMdCell escaping, arg parse + mutex), and 19 new offline smoke checks in the doctor group. 368/368 zig tests, 113/113 doctor smoke checks green.
… + credential sweep --probe emits two rows per registry provider: probe_<name> (endpoint reachability — any HTTP response counts) and probe_<name>_auth (key resolved with the same precedence a run configured for that provider would use, then a one-token authenticated POST when a key is found). Only the key's source label is ever reported — never the key itself. The configured provider probes its resolved endpoint/model (TAU_ENDPOINT/--model honored); auth rows skip when the endpoint probe failed, when offline, when curl is missing, or when no credential resolves. Rows stream as NDJSON check events under --json and appear in the --report checks table. Without --probe a single skipped provider_probes row advertises the sweep. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ng onboarding Adds a "clients" step between completions and doctor in `tau setup`: - `--client zed|vscode|jetbrains` writes a minimal settings file (agent_servers.tau / acp.agents.tau) with the absolute path of the running binary, so GUI editors that lack PATH lookups still resolve it. - Existing settings files are never rewritten — they're JSONC and a parse-and-rewrite would destroy comments. If a "tau" entry is already present (checked via JSONC-aware parse) the entry reports already_installed; otherwise a paste-ready fragment lands in ~/.config/tau/snippets/<client>.jsonc and the entry reports "manual". - `--client nvim` always reports manual: Neovim ACP plugins are Lua config, so setup writes ~/.config/tau/snippets/nvim.lua with both the avante.nvim and CodeCompanion blocks plus an editor_detected flag. - Without --client the step is skipped and only reports which editor config dirs exist; detection never writes. - Manual outcomes pass the setup verdict; only IO failures fail it. Wired: args.zig enum validation (with "code" alias), Config.setup_client, help text, guide row, all four completion scripts, AGENTS.md, README, CHANGELOG, and a docs/acp.md shortcut note. 7 new unit tests cover parsing, paths, JSONC-aware tau-key detection, and the three write outcomes; 30 new offline smoke checks cover the flag end-to-end (324/324 unit, 73/73 setup group). Closes #219 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…check against a loopback stub Adds a `selftest` check row that spawns the running tau binary with a fully scrubbed environment — every provider env key, TAU_API_KEY, TAU_ENDPOINT and TAU_DEBUG_LOG stripped, HOME pointed at a throwaway dir so no real config can leak in — plus a stub TAU_API_KEY and a TAU_ENDPOINT aimed at an in-process loopback HTTP stub (std.Io.net, no python/sh dependency, Windows-safe). The child must return the canned marker end-to-end (one-shot, --no-tools --no-stream) for the row to report ok; exit code and truncated stderr/stdout excerpts are surfaced on failure. The stub serves up to 4 connections (the provider HTTP layer retries) and is reaped by a done-flag + self-connect kick so a blocked accept() never deadlocks the check. Deliberately not gated on --offline: the stub is loopback-only, so `tau doctor --offline --selftest` is a fully hermetic install check. Skips only when curl is unavailable (the child shells out to curl). Wires --selftest through args parsing, Config, help_text, the guide table, all four shell completions, smoke coverage (env-scrub and isolation assertions included), README/AGENTS.md/troubleshooting/ configuration docs, and CHANGELOG. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…attended onboarding tau setup never prompts and never reads stdin — the new flags make that contract explicit for devcontainers, dotfiles scripts, and CI: - `--yes`/`-y` approves all write steps; `--non-interactive` declares the unattended run. Both are recorded in the verdict as "non_interactive":true/"yes":true so scripts can assert on them. - Env equivalents honored at parse time with flag > env > detect precedence: TAU_YES, TAU_NONINTERACTIVE (truthy = 1/true/yes/on), TAU_SETUP_SHELL, TAU_SETUP_CLIENT (validated like the flags; invalid values exit 80). - CI is deliberately not auto-detected — scripts opt in explicitly. - Shared validSetupShell/validSetupClient validators + envTruthy helper; 5 new parse tests + an unattended() unit test. - Help text, embedded guide, all four completions, README, CHANGELOG, AGENTS.md, and docs/configuration.md env table updated. - 30 new smoke checks in the setup group: flag/env-triggered mode, flag beats env, falsy env ignored, invalid env -> 80, stdin-closed run. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
# Conflicts: # README.md # completions/tau.ps1 # src/config.zig # src/main.zig
# Conflicts: # CHANGELOG.md # scripts/smoke.sh
# Conflicts: # CHANGELOG.md # scripts/smoke.sh # src/args.zig
…or --selftest)
Adds a `first-run` job to the ci workflow that locks the documented
first-run path for every released platform (linux x86_64/aarch64, macos
x86_64/aarch64, windows x86_64):
- builds tau, stages it as a local release tree
(srv/latest/download/<asset> + SHA256SUMS.txt — the exact layout the
installers fetch), and installs it through the shipped installer —
install.sh on POSIX legs, install.ps1 on the Windows leg — against a
file:// TAU_BASE_URL so nothing touches the network;
- then drives scripts/e2e-first-run.{sh,ps1} against the INSTALLED binary
in a scratch HOME with every credential source scrubbed:
`tau setup --yes --offline` (unattended onboarding: config scaffolded,
verdict ok/yes/non_interactive), `tau doctor --offline --selftest`
fully credential-free (asserts the selftest check row reports ok — the
feature's promise — while the keyless verdict honestly exits non-zero),
and the same doctor run with a fake resolvable key (asserts exit 0).
The release workflow's install-smoke jobs now assert the same selftest
check row on the shipped artifacts, so published binaries are verified to
self-test too. A new `first-run` smoke group pins the drivers, the ci.yml
wiring, and runs the POSIX driver end-to-end against zig-out/bin/tau.
Branch carries the prerequisite chain merges: mago/task-222 (doctor
--selftest), mago/task-230 (setup --yes/--non-interactive), mago/task-182
(install.sh + install.ps1 + release.yml), mago/task-193 (ci matrix).
Verified: zig build test 392/392, full offline smoke 625/625, and the
complete install.sh file:// → e2e-first-run.sh chain run locally.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9552c8c777
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return .{ .name = "endpoint_reachable", .status = .skip, .message = "skipped (curl unavailable)" }; | ||
|
|
||
| const code = curlHttpCode(io, gpa, &.{ | ||
| "curl", "-s", "-o", "/dev/null", "-w", "%{http_code}", |
There was a problem hiding this comment.
Use a Windows-compatible curl output sink
On native Windows, every non---offline doctor run reaches this command, but curl documents nul rather than /dev/null as the Windows output target (curl docs). The output-file open fails, curlHttpCode returns null, and a reachable endpoint is reported as failed; this also makes the doctor step in a normal tau setup fail. Select NUL by target platform (or discard captured output without a pathname) for this and the equivalent auth/probe calls.
AGENTS.md reference: AGENTS.md:L383-L387
Useful? React with 👍 / 👎.
| @@ -0,0 +1,2221 @@ | |||
| // `tau doctor` — offline-first setup diagnostics. Validates the whole setup | |||
There was a problem hiding this comment.
Split doctor diagnostics into compliant modules
This newly added module is 2,221 lines, far beyond the repository's under-500-LOC requirement. Split the diagnostics checks, serialization, remediation, and self-test responsibilities into focused modules; retaining this monolith violates the documented project structure and makes future changes difficult to review and test.
AGENTS.md reference: AGENTS.md:L571-L571
Useful? React with 👍 / 👎.
| @@ -0,0 +1,1123 @@ | |||
| // `tau setup` — one-shot onboarding: scaffold ~/.config/tau/config.json | |||
There was a problem hiding this comment.
Split onboarding code into compliant modules
This newly added onboarding module is 1,123 lines, exceeding the repository's under-500-LOC requirement by more than double. Separate completion installation, editor-client configuration, and setup orchestration into focused modules before merging so this new subsystem follows the required project structure.
AGENTS.md reference: AGENTS.md:L571-L571
Useful? React with 👍 / 👎.
| @@ -0,0 +1,504 @@ | |||
| //! Redacted diagnostic log file for bug reports (`--debug`). | |||
There was a problem hiding this comment.
Split the debug logger below the file-size limit
The newly added debug logger is 504 lines, which exceeds the repository's strict under-500-LOC source-file limit. Move the masking implementation or the logging lifecycle into a focused module so this file complies with the documented limit.
AGENTS.md reference: AGENTS.md:L571-L571
Useful? React with 👍 / 👎.
| .zsh => try std.fmt.allocPrint(arena, "{s}/.zshrc", .{home}), | ||
| // pwsh profile location on Linux/macOS. Windows users can copy the | ||
| // same line into the profile shown by `pwsh -NoProfile -c '$PROFILE'`. | ||
| .pwsh => try std.fmt.allocPrint(arena, "{s}/.config/powershell/Microsoft.PowerShell_profile.ps1", .{home}), |
There was a problem hiding this comment.
Write the PowerShell hook to the active Windows profile
On native Windows, tau setup --shell pwsh appends the source line to <HOME>/.config/powershell/..., which PowerShell does not load: the current-user pwsh profile is under $HOME\Documents\PowerShell (Microsoft documentation). Setup reports success, but newly opened Windows pwsh sessions never source tau.ps1; resolve the Windows profile path (and account for Windows PowerShell's Documents\WindowsPowerShell path) instead.
AGENTS.md reference: AGENTS.md:L281-L282
Useful? React with 👍 / 👎.
| pub fn clientSettingsPath(arena: std.mem.Allocator, home: []const u8, k: ClientKind) !?[]u8 { | ||
| return switch (k) { | ||
| .zed => try std.fmt.allocPrint(arena, "{s}/.config/zed/settings.json", .{home}), | ||
| .vscode => try std.fmt.allocPrint(arena, "{s}/.config/Code/User/settings.json", .{home}), |
There was a problem hiding this comment.
Select VS Code settings paths by platform
tau setup --client vscode uses this Linux-only path on macOS and Windows, so it reports installation after creating a file VS Code never reads. VS Code's documented user settings paths are ~/Library/Application Support/Code/User/settings.json on macOS and %APPDATA%\Code\User\settings.json on Windows (VS Code documentation). Choose the settings directory by target platform so the ACP entry is actually discovered.
AGENTS.md reference: AGENTS.md:L300-L302
Useful? React with 👍 / 👎.
Summary
Adds a clean-environment first-run e2e to CI that locks the documented install → onboard → self-verify path for every released platform.
ciworkflow — newfirst-runjob (5-leg matrix: linux x86_64/aarch64, macos x86_64/aarch64, windows x86_64):srv/latest/download/<asset>+SHA256SUMS.txt, the exact layout the installers fetch.install.shon POSIX legs,install.ps1on the Windows leg — against afile://TAU_BASE_URL, so nothing touches the network.scripts/e2e-first-run.sh(POSIX) /scripts/e2e-first-run.ps1(Windows) against the installed binary in a scratchHOMEwith every credential source scrubbed:tau setup --yes --offline— unattended onboarding; assertsconfig.jsonis scaffolded and the verdict recordsok/yes/non_interactive. A fake provider key stands in for a user who already exported one;--offlinekeeps the leg hermetic.tau doctor --offline --selftestwith zero credentials — asserts theselftestcheck row reports"ok"(the feature's credential-free promise; the overall verdict honestly exits non-zero with no key, so the assertion is on the check row, not the exit code).releaseworkflow — thesmokeandsmoke-windowsinstall-verify jobs now assert the sameselftestcheck row on the shipped artifacts, so published binaries are verified to self-test before release.scripts/e2e-first-run.{sh,ps1}— the e2e drivers are standalone scripts so the same check runs locally:./scripts/e2e-first-run.sh ./zig-out/bin/tau.first-runsmoke group — 27 offline checks pinning the driver scripts, theci.yml/release.ymlwiring (drift guards), and an end-to-end run of the POSIX driver against the built binary.Stacked base
This branch merges the prerequisite chains the e2e exercises:
mago/task-222—tau doctor --selftest(feat(doctor): addtau doctor --selftest— credential-free e2e session against a loopback stub #225)mago/task-230—tau setup --yes/--non-interactive(feat(setup): add --yes/--non-interactive + TAU_* env fallbacks for unattended onboarding #231)mago/task-182—install.sh+install.ps1+release.yml(feat(release): Windows install.ps1 + winget/Scoop manifests + native Windows smoke #183)mago/task-193— theciworkflow matrix (ci: run unit tests + offline smoke groups on a Linux/macOS/Windows runner matrix #194)Merge conflicts resolved as unions (README, completions, CHANGELOG, args.zig — adapted
parseArgvEnvto task-193's plain-sliceparsesignature — main.zig guide text, smoke.sh group registry/functions).Verified
zig build test— 392/392./scripts/smoke.sh(full offline suite) — 625/625, 1 skipped./scripts/smoke.sh --group first-run— 27/27install.shviafile://→e2e-first-run.sh→ PASSinstall.ps1+e2e-first-run.ps1) is exercised in CI;doctor --selftestis platform-neutral (in-process loopback stub + env-scrubbed child spawn).Closes #233 (mago task #233)