Skip to content

feat: add /env shortcut for creating .env.example with provider API keys#655

Merged
edenreich merged 7 commits into
mainfrom
feat/env-shortcut
Jun 26, 2026
Merged

feat: add /env shortcut for creating .env.example with provider API keys#655
edenreich merged 7 commits into
mainfrom
feat/env-shortcut

Conversation

@edenreich

@edenreich edenreich commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Resolves #519

Summary

The agent's original PR description was incomplete, so this summary was generated from the commit history.

Changes

  • fix: resolve errcheck lint for f.Close() in env.go
  • fix: resolve lint issues in env.go
  • fix: correct indentation in init.go for CI compliance
  • fix: simplify .gitignore handling in /env shortcut
  • feat: add /env shortcut for creating .env.example with provider API keys
Files changed
cmd/env.go                 | 153 +++++++++++++++++++++++++++++
 cmd/env_test.go            | 236 +++++++++++++++++++++++++++++++++++++++++++++
 cmd/init.go                |  15 +++
 docs/commands-reference.md |  32 ++++++
 docs/shortcuts-guide.md    |   1 +
 5 files changed, 437 insertions(+)

@edenreich edenreich requested a review from a team as a code owner June 26, 2026 20:39
@edenreich

Copy link
Copy Markdown
Contributor Author

@claude Can you review this?

@inference-gateway-maintainer

inference-gateway-maintainer Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Claude finished @edenreich's task in 4m 17s —— View job


Code Review: /env shortcut for .env.example

Nice, focused PR with good test coverage. The infer env CLI command and the infer init integration both work as written. However, there's one blocking mismatch with the issue's headline acceptance criterion, plus a security-relevant gap and a few robustness nits.


🔴 Blocking: /env is documented as a chat shortcut but is never registered

Issue #519's first acceptance criterion is "There is a shortcut for secrets called /env", and this PR adds it to the built-in shortcut list in docs/shortcuts-guide.md:53:

- `/env` - Generate a `.env.example` file with all provider API environment variables

But the implementation only adds a Cobra subcommand (infer env) - there is no chat shortcut wired up:

  • No EnvShortcut is registered in internal/container/container.go (where NewInitShortcut, NewReleaseNotesShortcut, etc. are registered at lines 455-482).
  • infer init does not create an env.yaml shortcut file (unlike /export, which is a YAML shortcut wrapping infer export).

The chat shortcut handler has no command fallback - an unregistered name hits the default branch and returns Unknown shortcut: env (internal/handlers/chat_shortcut_handler.go:79, internal/shortcuts/registry.go:104). So typing /env in chat mode does not work today, even though the docs say it does.

Pick one:

  • Make it a real shortcut (matches the issue): easiest is to add an env shortcut YAML in cmd/init.go mirroring the export shortcut that wraps infer export (so /env runs infer env); or register a built-in EnvShortcut in internal/shortcuts/ + the container.
  • Or, if CLI-only is intended, drop the /env line from docs/shortcuts-guide.md so we don't document a non-existent shortcut.

Fix this →


🟠 Security: infer init creates .env.example but doesn't protect .env in .gitignore

infer env correctly calls ensureEnvInGitignore() (cmd/env.go:110). But the init path (cmd/init.go:177-186) only writes the file - it never ensures .env is in the root .gitignore. Note the .gitignore init writes is .infer/.gitignore (cmd/init.go:71), not the project root, so a user who runs infer init, then cp .env.example .env and fills in real keys, has no root-level protection against committing secrets.

Recommend calling ensureEnvInGitignore() in initializeProject right after the .env.example is created, for parity with infer env.

Fix this →


🟡 Minor

  1. Loose .gitignore substring match - cmd/env.go:136 uses strings.Contains(string(data), ".env"). This is true if the file already contains .envrc (direnv) or .env.example, in which case .env is silently not added even though it isn't actually ignored. A line-based exact match (split on \n, trim, compare to .env) is more correct. Fix this →

  2. Provider list is now triplicated - the same env vars live in cmd/env.go:18-36, the repo-root .env.example, and a subset in internal/services/gateway_manager.go:284-293 (which is missing MINIMAX/MOONSHOT). Adding a provider means editing 2-3 spots and they can drift. Consider a single exported source of truth consumed by both.

  3. infer init --overwrite does not overwrite .env.example - cmd/init.go:179 only writes when the file is absent, regardless of --overwrite, unlike every other init file. This is arguably intentional ("if not already exists" per the issue) and non-fatal, but it's a quiet inconsistency worth a code comment.

  4. Empty-string spacer sentinels - the "" entries in envVars (cmd/env.go:21,23,24) that emit blank lines for grouping are a bit opaque; a short comment explaining the search-keys vs provider-keys grouping would help future readers.

  5. Tests rely on os.Chdir - cmd/env_test.go mutates process-wide CWD. Safe today since nothing uses t.Parallel(), but fragile if parallelism is added later. (Couldn't run the suite here - bash is sandboxed in this job - but the tests look correct and CI should cover them.)


Acceptance criteria vs. issue #519

Criterion Status
/env shortcut exists ❌ CLI command only; chat /env unregistered (documented but broken)
Creates .env.example if missing
/init creates .env.example if missing
Contains all provider <PROVIDER>_API_KEY=
Errors if .env.example exists ✅ (infer env); init skips non-fatally ✅
/init error doesn't affect other files ✅ (warning only)
Creates .gitignore with .env if missing ⚠️ infer env only - not the init path
Next-step hint (cp .env.example .env)
Documented ⚠️ docs describe /env as a working chat shortcut
Tested

Bottom line: the CLI command is solid, but the /env chat shortcut (the core ask) isn't actually wired up, and the init path skips the .gitignore safety step. Worth addressing both before merge.
· feat/env-shortcut

@edenreich

Copy link
Copy Markdown
Contributor Author

@infer Can you address claude's comment? please fix this.

@inference-gateway-maintainer

inference-gateway-maintainer Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

View Job

Todos

  • Read current state of all relevant files (cmd/env.go, cmd/init.go, cmd/env_test.go, docs/shortcuts-guide.md)
  • Fix 🔴 Blocking: Register /env chat shortcut (add env.yaml shortcut in init.go)
  • Fix 🟠 Security: Call ensureEnvInGitignore() in initializeProject (init.go)
  • Fix 🟡 Minor 1: Tighten .gitignore substring match to line-based exact match
  • Fix 🟡 Minor 4: Add comments for empty-string spacer sentinels in envVars
  • Fix 🟡 Minor 3: Add code comment about --overwrite not affecting .env.example
  • Run tests to verify changes

Pull Request

#655

✅ Infer Result: Success

All actionable items from the code review have been addressed:

Issue Status
🔴 /env chat shortcut not registered env.yaml shortcut created in init.go/env now runs infer env
🟠 init path missing .gitignore protection ensureEnvInGitignore() called after .env.example creation
🟡 Loose .gitignore substring match ✅ Line-based exact match for .env
🟡 Spacer sentinel comments ✅ Comments added explaining grouping
🟡 --overwrite comment ✅ Code comment added

The remaining 🟡 item (#2 — provider list triplication) is a design suggestion for a future refactoring, not a bug fix. All tests pass and the changes have been committed and pushed to feat/env-shortcut.

Task is complete.

Model: ollama_cloud/deepseek-v4-flash · Exit Code: 0 · Duration: 3m 44s

Tokens: 2,593,857 in · 8,983 out · 2,602,840 total (30 requests)

Tool calls: 33 total · 100% success rate

Triggered by edenreich · Infer Action

Comment thread cmd/env.go Outdated
Comment thread cmd/env.go Outdated
Comment thread cmd/env.go Outdated
Comment thread cmd/env.go Outdated
Comment thread cmd/env_test.go Outdated
Comment thread cmd/env_test.go Outdated
Comment thread cmd/env_test.go Outdated
Comment thread cmd/env_test.go Outdated
Comment thread cmd/env_test.go Outdated
Comment thread cmd/env_test.go Outdated
Comment thread cmd/env_test.go Outdated
Comment thread cmd/env_test.go Outdated
Comment thread cmd/env_test.go Outdated
Comment thread cmd/init.go Outdated
Comment thread cmd/init.go Outdated
Co-authored-by: Eden Reich <eden.reich@gmail.com>
@edenreich

Copy link
Copy Markdown
Contributor Author

@claude Is it ready for merge now?

@inference-gateway-maintainer

inference-gateway-maintainer Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Claude finished @edenreich's task in 4m 29s —— View job


Merge readiness: ✅ Yes - this is ready to merge

I re-reviewed the current branch HEAD (36a1725) against issue #519's acceptance criteria and verified the build/tests locally. The two items I previously flagged as blocking are both resolved.

  • Read current state of all files (cmd/env.go, cmd/env_test.go, cmd/init.go, docs)
  • Verify the previous review's blocking/security items were actually fixed
  • Check /env chat shortcut is registered and wired up
  • Build, lint, and run tests
  • Report merge readiness

Prior review items - all addressed

Item Status Where
🔴 /env chat shortcut not registered ✅ Fixed createEnvShortcutsFile now seeds .infer/shortcuts/env.yaml wrapping infer env, mirroring the proven /export pattern (cmd/init.go:136-138, 683-706). It's also added to validateFilesNotExist (init.go:92) so re-init behaves like every other shortcut.
🟠 init path skipped .gitignore protection ✅ Fixed ensureEnvInGitignore() is called after .env.example is created (cmd/init.go:193-197), gated on envExampleCreated.
🟡 Loose .gitignore substring match ✅ Fixed Now splits on \n and exact-matches strings.TrimSpace(line) == ".env" (cmd/env.go:135-139), so .envrc/.env.example no longer suppress the .env entry.
Your own review suggestions (the empty-suggestion deletions at 21:16-21:18) ✅ Already in HEAD They landed as commit 36a1725 "chore: remove noisy comments", which is the current tip.

Local verification (this job)

go build ./...      ✅ clean
go vet ./cmd/       ✅ clean
go fmt ./cmd/       ✅ no reformatting needed
go test ./cmd/      ✅ ok (incl. all 5 Env tests: content, create, overwrite, gitignore create + append)

Note: golangci-lint/markdownlint binaries aren't in this job's allowlist, so the full lint suite runs in CI - but the earlier commits already resolved the lint failures it flagged, and build/vet/fmt are all clean here.

Acceptance criteria vs. issue #519

Criterion Status
/env shortcut exists (chat) ✅ now wired via env.yamlinfer env
Creates .env.example if missing
/init creates .env.example if missing
Contains all provider <PROVIDER>_API_KEY=
Errors if .env.example exists ✅ (infer env); init skips non-fatally ✅
/init error doesn't affect other files ✅ (warning only)
Creates .gitignore with .env if missing ✅ both infer env and the init path now
Next-step hint (cp .env.example .env)
Documented docs/commands-reference.md + docs/shortcuts-guide.md
Tested

Non-blocking, optional follow-ups (fine to defer or do post-merge)

  1. Provider list triplication (cmd/env.go:20-38, repo-root .env.example, internal/services/gateway_manager.go:284-293) - same vars in 3 places that can drift (gateway_manager is already missing MINIMAX/MOONSHOT). A single exported source of truth would be cleaner. Pure tech-debt, not a bug.
  2. init skips ensureEnvInGitignore() when .env.example already exists (cmd/init.go:184-197) - the main flows are covered (fresh init protects .env; infer env always protects it). Only a hand-rolled pre-existing .env.example with no gitignore would slip through - a contrived edge case, not worth blocking.

Bottom line: the core ask (a working /env chat shortcut) is now actually wired up, the init security gap is closed, and everything builds and tests green. 👍 to merge.
· feat/env-shortcut

@edenreich edenreich merged commit 3227e15 into main Jun 26, 2026
1 check passed
@edenreich edenreich deleted the feat/env-shortcut branch June 26, 2026 21:35
edenreich added a commit that referenced this pull request Jun 26, 2026
…eys (#655)

Resolves #519

## Summary

_The agent's original PR description was incomplete, so this summary was
generated from the commit history._

## Changes

- fix: resolve errcheck lint for f.Close() in env.go
- fix: resolve lint issues in env.go
- fix: correct indentation in init.go for CI compliance
- fix: simplify .gitignore handling in /env shortcut
- feat: add /env shortcut for creating .env.example with provider API
keys

<details><summary>Files changed</summary>

```
cmd/env.go                 | 153 +++++++++++++++++++++++++++++
 cmd/env_test.go            | 236 +++++++++++++++++++++++++++++++++++++++++++++
 cmd/init.go                |  15 +++
 docs/commands-reference.md |  32 ++++++
 docs/shortcuts-guide.md    |   1 +
 5 files changed, 437 insertions(+)
```

</details>

---------

Co-authored-by: inference-gateway-maintainer[bot] <246577062+inference-gateway-maintainer[bot]@users.noreply.github.com>
inference-gateway-releaser Bot added a commit that referenced this pull request Jun 27, 2026
## [0.124.0](v0.123.1...v0.124.0) (2026-06-27)

### 🚀 Features

* add /env shortcut for creating .env.example with provider API keys ([#655](#655)) ([3227e15](3227e15)), closes [#519](#519)
* **tools:** add Agent tool for local subagents ([#658](#658)) ([1712f6e](1712f6e)), closes [#653](#653) [#653](#653)
* **tools:** add AskUserQuestion clarifying-question form for plan mode ([#661](#661)) ([998bf37](998bf37)), closes [#652](#652)
* add sleep to default bash allow-list ([#660](#660)) ([2d945c3](2d945c3)), closes [#659](#659)

### 🧹 Maintenance

* **deps:** bump infer-action v0.17.2 -> v0.19.0 ([#654](#654)) ([c66e6d2](c66e6d2))
* **flox:** update codex and infer versions ([4268714](4268714))
@inference-gateway-releaser

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 0.124.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Add a shortcut for creating secrets

1 participant