Skip to main content

Developer-first CLI for personalized food and dietary guidance from hello.food.

Project description

heyfood

Developer-first command-line access to personalized food and dietary guidance from hello.food.

heyfood is the open-source CLI client. It provides terminal-native workflows for dietary profiles, food checks, restaurant and menu discovery, recipes, meal logging, and the hello.food conversational agent. Guidance is provided by the hosted hello.food service and is not a substitute for professional medical advice or emergency care.

Installation

Install the isolated command with pipx:

pipx install heyfood-cli
heyfood --version
heyfood --help

Python 3.11, 3.12, and 3.13 are supported. To use the operating-system credential vault instead of the secure file fallback, install the optional keyring extra:

pipx install 'heyfood-cli[keyring]'

Contributors can install from a reviewed source checkout:

git clone https://github.com/frntrllc/heyfood.git
cd heyfood
python3.11 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e .
# Optional: store tokens in the operating-system credential vault
python -m pip install -e '.[keyring]'
heyfood --version
heyfood --help

Authenticate

heyfood login
heyfood status
heyfood doctor

Login opens a browser for explicit hello.food consent and stores the resulting CLI credentials securely. On an SSH/headless machine, use the short-code flow:

heyfood login --device --no-browser

Open the printed URL on any browser, confirm that the displayed code matches the terminal, review the same capability list, and approve. The remote machine never needs a reachable loopback callback.

Common workflows

heyfood ask "What can I order at this restaurant?"
heyfood reply "Log the first option"
heyfood chat

heyfood item "pad thai" --restaurant "Pismo's"
heyfood search --near "Fresno, CA" --query "thai"
heyfood menu 1
heyfood recommend 1 --query "low-FODMAP dinner"

heyfood recipes search "Mediterranean dinner" --max-ready-time 35
heyfood recipes save 1
heyfood recipes saved

heyfood onboard
heyfood profile
heyfood members list
heyfood household list
heyfood household use everyone
heyfood daily today

heyfood conversation list
heyfood conversation resume "What about the second option?"

Agent and direct commands render confirmations, safety verdicts, restaurant/menu summaries, recipe ideas, and meal nutrition as terminal-native output. The product uses “generally safer,” “risky,” “avoid,” and “unable to evaluate” rather than presenting food as absolutely safe.

See the command grammar for positional inputs, selectors, compatibility aliases, and the rationale for optional search flags.

recommend shows a composite Match rank and ranking confidence, not a safety verdict. Each row includes an heyfood item ... command for the separate safety evaluation. The ranking and canonical safety JSON contracts are defined in the versioned schema guide.

Location

Restaurant search accepts coordinates, a one-off place name, or a saved default:

heyfood location set "San Luis Obispo, CA"
heyfood location set --lat 35.28 --lng -120.66 --label Home
heyfood location show

heyfood search --query "thai"
heyfood search --near "Fresno, CA" --query "thai"
heyfood search --lat 36.74 --lng -119.79 --query "thai"

heyfood location clear

Explicit coordinates take precedence over --near, which takes precedence over the saved location. Place-name lookup requires a service deployment that supports the geocoding channel tool.

Search and recipe results are remembered locally so later commands can use a numbered selector such as heyfood menu 1 or heyfood recipes save 2.

Saved location is also supplied to ask, reply, and chat when no explicit location is provided. Override it with --lat/--lng or --near, or suppress location for a request with --no-location.

Households and conversational scope

heyfood can ask for you, one household member, or everyone. The local roster mirrors the mobile app's local-first household model. Adult dietary graphs are loaded from profile sync only for the active turn; child graphs remain local.

heyfood household list
heyfood household label MEMBER_ID --name Sarah --relationship spouse

heyfood household use Sarah
heyfood ask "What can she order here?"

heyfood ask --for everyone "What can we all eat?"
heyfood chat --for Sarah

household list discovers synced member profile ids. Because names and relationships remain device-local by design, a member created in the mobile app may first appear by id; use household label once on this machine. Child members remain device-local and do not appear through sync. Inside chat, /household shows the roster and /for Sarah, /for everyone, or /for me switches scope and starts a fresh conversation. Numbered agent choices can be answered with 2 or, for multi-select questions, 1, 3.

On an account without profile-sync consent, household list still returns the local roster and marks synced-member reconciliation as skipped in JSON output. Other authentication and service errors remain failures rather than being silently hidden.

As in the mobile app, child dietary profiles stay on this machine and never enter profile sync. Other members' dietary graphs are loaded from profile sync only for the active agent turn. If an adult profile write fails, heyfood keeps the confirmed change in a protected local outbox, includes its full safety context in later turns, and automatically retries it on a consented scoped agent turn. A later mutation merges with pending fields instead of replacing them, so subsequent safety checks do not silently lose an allergy write.

Dietary graph onboarding

Run heyfood onboard for the guided questionnaire, or start with natural language and review the extracted values:

heyfood onboard "I'm low-FODMAP, avoid onion and garlic, and prefer Thai food"

In an interactive terminal, heyfood shows the extracted sections first, lets you reject them in favor of the full questionnaire, and asks only for sections the text did not answer. Explicit statements such as “no food allergies” count as answered and are not prompted again.

Repeatable automation can pass fields directly:

heyfood onboard \
  --diet low-fodmap \
  --condition IBS \
  --allergy peanuts \
  --avoid onion \
  --avoid garlic \
  --cuisine Thai \
  --activity moderate \
  --yes \
  --no-input

Use heyfood onboard --list-options to inspect accepted labels and identifiers, --dry-run to preview the profile payload, and heyfood profile to inspect the synced graph. --no-input guarantees the command will never prompt; mutations must combine it with --yes. Passing none (or an explicit empty repeatable field from an API caller) clears only that source category and its derived values; unrelated diet, allergy, condition, avoid, cuisine, and activity data is preserved. --replace discards the complete existing graph before applying the supplied fields.

Machine output

Use --json for automation. Data commands emit exactly one ANSI-free JSON value to stdout; progress, hints, and deprecation warnings use stderr. The existing --raw flag is a deprecated compatibility alias for the same writer.

See the CLI process contract for JSON errors, exit codes, prompt behavior, and compatibility policy.

Add global --verbose before a command to print safe request diagnostics to stderr while leaving result/JSON stdout unchanged:

heyfood --verbose doctor --json
heyfood --verbose ask "Can I eat pad thai?" --json

Diagnostics include a generated request id, method/path, selected context, status, timing, and auth refresh/retry event names. They never include request bodies, query text, tokens, API keys, dietary profile contents, or phone numbers.

Shell completion

Install completions once for the current shell:

heyfood --install-completion  # auto-detects zsh, bash, or fish

To review or manage the script yourself, use heyfood --show-completion. Restart the shell after automatic installation. In dotfile-managed setups, capture the generated script instead of letting the CLI edit a shell file.

Configuration

Configuration is stored at ~/.config/heyfood/config.json by default, or under $XDG_CONFIG_HOME/heyfood/config.json when XDG_CONFIG_HOME is set. The client keeps the directory owner-only and the file mode at 0600. Install the optional keyring extra to keep access tokens, refresh tokens, local API keys, household identity, local-only child dietary profiles, and pending profile-sync repairs in the operating-system credential vault; the JSON file then contains only non-secret state and a credential_store: "keyring" marker.

Confirmation previews can contain names, birth dates, and dietary data. They are persisted only in the credential vault and are omitted from both the JSON file and heyfood config show; without a usable vault, heyfood does not persist the preview between processes. Local household state is bound to the authenticated account and is cleared fail-closed when a different account logs in (including legacy unbound state on the first upgraded login).

On headless systems without a usable keyring, credentials and protected household state remain in the 0600 file. This protects them from other local users under normal permissions, but not from malware or another process running as the same OS account. Set HEYFOOD_CREDENTIAL_STORE=file to choose that fallback explicitly, or HEYFOOD_CREDENTIAL_STORE=keyring to fail instead of falling back when the vault is unavailable. Never copy either credential store between machines.

Authorized development environments can override service endpoints without editing the config file:

export HEYFOOD_API_URL="https://api.example.test"
export HEYFOOD_AUTH_URL="https://auth.example.test/authorize"
export HEYFOOD_API_KEY="..."

Named contexts make production, local, and custom environments explicit:

heyfood context list
heyfood context use local
heyfood context set staging \
  --api-url https://api.staging.example \
  --auth-url https://auth.staging.example/authorize \
  --use
heyfood context show

Precedence is command flags, then HEYFOOD_API_URL/HEYFOOD_AUTH_URL, then the selected context. heyfood login --local remains a convenient one-command override. Inspect configuration without revealing credentials:

heyfood config path
heyfood config show --json
heyfood config validate

config show redacts all token and API-key fields. If validation reports malformed JSON, move the named file aside and rerun heyfood login; read-only configuration and doctor commands do not mint a device id or create config.

Terminal branding and accessibility

The full hey.food banner appears only on compatible interactive terminals while a genuinely slow operation is starting, and at most once per process. It is never written to JSON/result stdout, never adds a delay, and is suppressed for CI, redirected output, TERM=dumb, and non-interactive input. Terminals narrower than 44 columns or unable to encode the block glyphs use a compact hey.food welcome instead.

Use either control to disable decorative branding for screen readers or personal preference:

heyfood --no-banner
export HEYFOOD_NO_BANNER=1

NO_COLOR=1 keeps supported banner geometry but removes color.

Never commit the config file, tokens, or API keys. Public issues and fixtures must use synthetic dietary and account data.

Development and support

Uninstall

Revoke the local session before removing the package:

heyfood logout
python -m pip uninstall heyfood-cli

For a future pipx installation, use pipx uninstall heyfood-cli after logout. If logout cannot reach the service, local credentials are still removed but server-side sessions may persist until expiry. Use heyfood logout --json to inspect per-step teardown results without exposing token values.

License and project boundary

Copyright 2026 FRNTR, LLC.

The heyfood CLI distribution is licensed under the Apache License 2.0. The license applies to this client and explicitly published public assets. It does not license the proprietary hello.food backend, hosted service, intelligence, models, prompts, data, evaluation rules, or infrastructure.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

heyfood_cli-0.2.0.tar.gz (100.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

heyfood_cli-0.2.0-py3-none-any.whl (100.1 kB view details)

Uploaded Python 3

File details

Details for the file heyfood_cli-0.2.0.tar.gz.

File metadata

  • Download URL: heyfood_cli-0.2.0.tar.gz
  • Upload date:
  • Size: 100.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for heyfood_cli-0.2.0.tar.gz
Algorithm Hash digest
SHA256 5a0a0557367e9b230c41c145dbb18b12685e5a4231f8d6b328b9db95e150f8d1
MD5 dfc6acbe55c40f21d65c339a5d2e7550
BLAKE2b-256 0f7fc4c68ea67dd384e4a08416345253cd5be8b2a111bd90d4e98a358bb50800

See more details on using hashes here.

Provenance

The following attestation bundles were made for heyfood_cli-0.2.0.tar.gz:

Publisher: release.yml on frntrllc/heyfood

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file heyfood_cli-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: heyfood_cli-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 100.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for heyfood_cli-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 93fcb58446816fff23d43d3b0a102105fa562d2015b8cdce1ccd447a06210786
MD5 cdfc6b5793dc4435963a2033ae3c272b
BLAKE2b-256 5102990623876569b8ade2e92be7b605e428b51eb6bec88c857acffe89567238

See more details on using hashes here.

Provenance

The following attestation bundles were made for heyfood_cli-0.2.0-py3-none-any.whl:

Publisher: release.yml on frntrllc/heyfood

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page