Skip to content

Add primitive doctor and friendlier network-failure hints#68

Merged
etbyrd merged 3 commits into
mainfrom
doctor-and-network-hint
May 11, 2026
Merged

Add primitive doctor and friendlier network-failure hints#68
etbyrd merged 3 commits into
mainfrom
doctor-and-network-hint

Conversation

@etbyrd
Copy link
Copy Markdown
Member

@etbyrd etbyrd commented May 11, 2026

Summary

AGX walkthroughs kept hitting ENETUNREACH from inside container environments where HTTPS_PROXY was exported but Node 22+ ignores it without NODE_USE_ENV_PROXY=1. The CLI's error envelope just said ENETUNREACH and nothing else; the agent had no actionable next step. They asked for a doctor command. This PR ships both halves: the doctor command plus a network-error hint layer so the existing commands stop being dead ends.

New command: primitive doctor

Runs five checks and prints an interactive checklist on stderr with OK/WARN/FAIL prefixes, then a JSON summary on stdout for piping. The checks cover the four things that actually fail in practice:

  1. Node version (against the >=22 minimum).
  2. Proxy env: surfaces NODE_USE_ENV_PROXY, HTTPS_PROXY, HTTP_PROXY, NO_PROXY. Specifically warns when HTTPS_PROXY is set without NODE_USE_ENV_PROXY=1, which is the AGX failure mode.
  3. API key resolution: flag, env, or saved login credentials.
  4. API auth: live /account roundtrip with the resolved key.
  5. Domains: listDomains, surfacing active domains so the user can confirm the managed *.primitive.email subdomain is verified.

Each non-OK row prints a hint line with the specific fix. The command exits 1 on any FAIL; WARN does not fail.

Network-error hints in writeErrorWithHints

Added NETWORK_ERROR_HINTS keyed by Node cause.code: ENETUNREACH, ECONNREFUSED, ETIMEDOUT, EAI_AGAIN. Every CLI command that already uses writeErrorWithHints (whoami, send, deploy, all generated operation commands) now prints a useful hint on network failure instead of the bare envelope. The hints reference NODE_USE_ENV_PROXY=1 and primitive doctor so the user has an immediate fix to try and a way to bisect further.

Tests

11 new tests (3 in doctor.test.ts covering renderRow / checkNode / checkProxy / checkApiKey, 8 in api-command.test.ts covering each network-error hint variant). All 154 cli-node tests green; lint and typecheck clean.

Release

Bumps cli-node from 0.24.0 to 0.24.2 so the new command and hint ship on the next CI publish.

Test plan

  • CI green.
  • After publish, primitive doctor in a fresh shell with valid PRIMITIVE_API_KEY shows 5 OK rows and exits 0.
  • unset PRIMITIVE_API_KEY && primitive doctor shows API key FAIL with the login hint and exits 1.
  • HTTPS_PROXY=http://localhost:9999 primitive whoami (or any command) returns an ENETUNREACH envelope followed by the NODE_USE_ENV_PROXY hint.

etbyrd added 2 commits May 11, 2026 00:38
AGX walkthrough kept hitting ENETUNREACH from inside container
environments where HTTPS_PROXY was set but Node 22+ ignores those
env vars without NODE_USE_ENV_PROXY=1. The bare envelope said
ENETUNREACH and nothing else, leaving the agent with no actionable
next step. They asked for a doctor command that checks the local
environment in one shot. This PR ships both halves.

New command: primitive doctor

Runs five checks and prints an interactive checklist on stderr with
OK/WARN/FAIL prefixes, then a JSON summary on stdout for piping:

1. Node version, against the >=22 minimum.
2. Proxy env vars (NODE_USE_ENV_PROXY, HTTPS_PROXY, HTTP_PROXY,
   NO_PROXY). Warns specifically when HTTPS_PROXY is set without
   NODE_USE_ENV_PROXY because that is the exact failure mode
   that produced the AGX runs ENETUNREACH symptom.
3. API key resolution from flag, env, or saved login credentials.
4. Live /account roundtrip with the resolved key.
5. listDomains, surfacing active domains so the user can confirm
   the managed *.primitive.email subdomain is verified.

Each non-OK row prints a hint line with the specific fix. Command
exits 1 if any FAIL check fires; WARN does not fail the run so
callers can pipe doctor through tooling without false negatives.

Network-error hints in writeErrorWithHints

Added a NETWORK_ERROR_HINTS map keyed by Node cause.code: ENETUNREACH,
ECONNREFUSED, ETIMEDOUT, EAI_AGAIN. Every other CLI command that
already routes through writeErrorWithHints (whoami, send, deploy,
the generated operation commands) now prints a useful hint on
network failure instead of the bare envelope. The hints point at
NODE_USE_ENV_PROXY=1 and primitive doctor so the user has both an
immediate fix to try and a way to bisect further.

Tests: 11 new (3 doctor command + 8 network-error hint variants).
All 154 cli-node tests green; lint and typecheck clean.

Bumps cli-node to 0.24.2 so the new command and hint ship on the
next CI publish.
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 11, 2026

Greptile Summary

This PR adds a primitive doctor command and a network-error hint layer to address the AGX container failure mode where ENETUNREACH was the only output. All three issues raised in previous review threads (HTTPS_PROXY vs HTTP_PROXY message accuracy, credentials.json "no api_key" vs "malformed" distinction, missing ETIMEDOUT test) are fully addressed in this diff.

  • primitive doctor: five-check health command (Node version, proxy env, API key, live account auth, verified domains) that writes a human-readable checklist to stderr and structured JSON to stdout; exits 1 on any FAIL, 0 on WARN-only.
  • Network hints in writeErrorWithHints: NETWORK_ERROR_HINTS keyed on cause.code (ENETUNREACH, ECONNREFUSED, ETIMEDOUT, EAI_AGAIN) appended after the existing ERROR_CODE_HINTS lookup, using the existing extractCauseDetails chain.
  • Tests: 154 tests passing; new doctor.test.ts covers all checkProxy env-var permutations, the credentials-file edge cases, and renderRow; api-command.test.ts covers all four network-error hint keys.

Confidence Score: 5/5

Safe to merge — the new command is additive, the hint layer touches only the trailing output of an existing error formatter, and no existing behavior is changed.

All changes are additive: a new command, a new read-only hint map, and a two-branch extension to the error output function. The previously raised issues are all addressed in the diff. The extractCauseDetails → extractErrorCode chain correctly propagates cause.code to the NETWORK_ERROR_HINTS lookup in production. No existing logic is altered.

No files require special attention.

Important Files Changed

Filename Overview
cli-node/src/oclif/commands/doctor.ts New primitive doctor command with five checks (Node version, proxy env, API key, account auth, domains); previously flagged issues with HTTPS_PROXY vs HTTP_PROXY message accuracy and credentials.json "no api_key" vs "malformed" distinction are both addressed in this diff.
cli-node/src/oclif/api-command.ts Adds NETWORK_ERROR_HINTS map and routes ENETUNREACH/ECONNREFUSED/ETIMEDOUT/EAI_AGAIN through writeErrorWithHints; leverages the existing extractCauseDetails → extractErrorCode chain which correctly reads error.cause.code on thrown fetch errors.
cli-node/tests/oclif/doctor.test.ts New test file covering renderRow formatting, checkNode, checkProxy (5 env-var scenarios including the HTTP_PROXY-only case), and checkApiKey (including the "valid JSON but no api_key" vs "malformed" split); good coverage of the edge cases that were previously flagged.
cli-node/tests/oclif/api-command.test.ts Adds four new tests covering each NETWORK_ERROR_HINTS key (ENETUNREACH, ECONNREFUSED, EAI_AGAIN, ETIMEDOUT); ETIMEDOUT test was missing from earlier review threads and is now present.
cli-node/src/oclif/index.ts Registers DoctorCommand under the doctor key in the COMMANDS map.
cli-node/package.json Version bumped from 0.24.1 to 0.24.2 to ship the new command and hints.

Reviews (2): Last reviewed commit: "Sharpen checkProxy and checkApiKey diagn..." | Re-trigger Greptile

Comment thread cli-node/src/oclif/commands/doctor.ts Outdated
Comment thread cli-node/src/oclif/commands/doctor.ts Outdated
Comment thread cli-node/tests/oclif/api-command.test.ts
Greptile flagged two inaccurate diagnostic paths in the doctor
command:

1. checkProxy hardcoded "HTTPS_PROXY set" in the warn message even
   when only HTTP_PROXY was set. A user debugging exactly the
   container failure mode this command exists to diagnose would
   read a contradiction between what the command reports and what
   the shell actually has. Rewrote to derive the var name(s) from
   process.env so the message names HTTP_PROXY, HTTPS_PROXY, or
   both depending on what's set.
2. checkApiKey labeled a credentials file that parsed as valid JSON
   but lacked an api_key field as "unreadable or malformed". Same
   bucket as a file that actually fails JSON.parse, which obscures
   the underlying issue. Split into two outcomes: "exists but
   contains no api_key" (file parsed) and "exists but is unreadable
   or malformed" (parse threw). The malformed path also surfaces
   the parser's error message so the user can see what was wrong
   without opening the file by hand.

Also added the test coverage Greptile flagged as missing: the
HTTP_PROXY-only warn path (which the original message bug masked),
the both-vars-set message format, and the ETIMEDOUT network hint
that was present in production code but unexercised.

162 cli-node tests green (5 new); lint and typecheck clean.
@etbyrd
Copy link
Copy Markdown
Member Author

etbyrd commented May 11, 2026

Addressed all three findings in 93efef1:

  1. checkProxy no longer hardcodes 'HTTPS_PROXY set' in the warn message. It now derives the var name(s) from process.env so the message reads 'HTTP_PROXY set' when only HTTP_PROXY is set, 'HTTPS_PROXY set' when only HTTPS_PROXY is set, and 'HTTPS_PROXY / HTTP_PROXY set' when both are set. The diagnostic now always names what the shell actually has.

  2. checkApiKey distinguishes 'credentials file parsed but no api_key field' from 'credentials file failed to parse'. The first now returns message 'exists but contains no api_key'; the second returns 'exists but is unreadable or malformed' plus the parser's error message. Same hint either way (logout + login).

  3. Added the missing test coverage: HTTP_PROXY-only warn path, both-vars-set message format, the empty-credentials-JSON case, the malformed-credentials-JSON case, and the ETIMEDOUT network hint. 162 cli-node tests green; lint and typecheck clean.

@etbyrd etbyrd merged commit 877d70f into main May 11, 2026
9 checks passed
@etbyrd etbyrd deleted the doctor-and-network-hint branch May 11, 2026 08:19
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.

1 participant