Skip to content

feat: installer-driven init flags + minimal nrq me [INT-444]#97

Merged
rianjs merged 2 commits into
mainfrom
feat/INT-444-installer-init-flags
May 18, 2026
Merged

feat: installer-driven init flags + minimal nrq me [INT-444]#97
rianjs merged 2 commits into
mainfrom
feat/INT-444-installer-init-flags

Conversation

@rianjs
Copy link
Copy Markdown
Collaborator

@rianjs rianjs commented May 18, 2026

Lets the central installer (~/monit/claude-desktop-mcp) drive nrq init non-interactively from installer-config.json (1Password refs → op run → env → --*-from-env).

Closes #96 · INT-444 (child of INT-310). Per maintainer fast-follow directive: single PR, no daemon / no TDD-assessment, Codex architect convergence (plan loop 0/0 over 2 rounds; one PR re-review) then admin-merge.

Changes

  • nrq init --account-id-from-env <ENV> — env-bridge for the non-secret account_id: same op→env→--*-from-env shape as --api-key-from-env (§1.5.1), but the resolved value lands in config.yml, never the keyring (§2.5). Mutually exclusive with --account-id; empty/unset env is a hard error (mirrors --api-key-from-env).
  • nrq init --non-interactive (init-only) — every interactive fallback becomes fail-loud (cli-deployment-manifest §1.3). Critically, the policy is threaded through a new keychain.OpenForInit(overwrite, nonInteractive)passphraseFunc(service, nonInteractive) so the file backend never prompts for a passphrase even on a TTY (the keychain opens before runInit's own prompt guards — caught by Codex as a blocker on the plan). Other Open* entry points unchanged.
  • nrq me — minimal identity/access check reusing TestConnection (no new api/ surface). RunE stays hardwired through opts.APIClient() (single credential chokepoint, no client injection); the pure evaluate() success predicate mirrors config test exactly (valid key AND, when an account is configured, account access) so the installer's verify: "me" cannot pass on a misconfigured account. The api_key is never rendered (§1.12).

Tests

--account-id-from-env installer-invocation e2e (config.yml set, keyring holds only api_key); empty-env + mutually-exclusive errors; --non-interactive no-key/no-ingress fail-loud; passphraseFunc(_, true) never-prompts (keychain unit, the Codex-blocker pin); renderMe table/json/plain with no key leak; evaluate() predicate table. No test makes a live New Relic call (init uses --no-verify; me logic tested via pure helpers).

Gate: gofmt · build · vet · 430 -race tests (29 pkgs) · go mod tidy no-drift · golangci-lint v2.0.2 0 issues · go 1.24.0.

rianjs added 2 commits May 18, 2026 18:47
Lets the central installer drive nrq init non-interactively from
installer-config.json (op -> env -> --*-from-env):

- nrq init --account-id-from-env <ENV>: env-bridge for the NON-secret
  account_id (same shape as --api-key-from-env per §1.5.1, but resolves
  into config.yml, NEVER the keyring — §2.5). Mutually exclusive with
  --account-id; empty/unset env is a hard error.
- nrq init --non-interactive (init-only): every interactive fallback
  becomes a fail-loud error (cli-deployment-manifest §1.3). The policy is
  threaded through a new keychain.OpenForInit(overwrite, nonInteractive)
  -> passphraseFunc(service, nonInteractive) so the file backend never
  prompts for a passphrase even on a TTY (the keychain opens before
  runInit's own prompt guards). Other Open* entry points unchanged.
- nrq me: minimal identity/access check reusing TestConnection (no new
  api/ surface). RunE stays hardwired through opts.APIClient() (single
  credential chokepoint); the success predicate (pure evaluate()) mirrors
  config test exactly — valid key AND, when an account is configured,
  account access — so the installer's verify:"me" can't pass on a
  misconfigured account. The api_key is never rendered (§1.12).

Tests: --account-id-from-env e2e (config.yml not keyring), empty-env and
mutually-exclusive errors, --non-interactive fail-loud, passphrase
non-interactive never-prompts (keychain unit), renderMe across
table/json/plain with no key leak, evaluate() predicate table. Docs
swept (README init/me, repo guide files: architecture + env table +
credentials).

Closes #96
Codex PR review: `nrq me` used cobra.NoArgs, which quotes args[0] in its
error — `nrq me NRAK-…` would echo a fat-fingered secret to stderr/logs,
the same §1.12 class fixed for init/set-credential. Switch to the existing
root.NoPositionalArgs static validator + a noleak regression.
@rianjs
Copy link
Copy Markdown
Collaborator Author

rianjs commented May 18, 2026

Blocker

  • None.

Major

  • None.

Minor

  • None.

Nit

  • None.

The updated diff matches the converged plan: --account-id-from-env stays non-secret and lands in config.yml, --non-interactive is init-scoped and reaches the file-backend passphrase path through OpenForInit, and nrq me preserves the API-client chokepoint while avoiding positional secret echo.

@rianjs rianjs merged commit 4fcb512 into main May 18, 2026
2 checks passed
@rianjs rianjs deleted the feat/INT-444-installer-init-flags branch May 18, 2026 22:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

nrq: installer-driven init flags (--account-id-from-env, --non-interactive) + minimal nrq me

1 participant