feat: arkenv example: update .env.example from the env schema - #1643
Conversation
Add arkenv sync so .env.example stays aligned with declared schema keys. Co-authored-by: Cursor <cursoragent@cursor.com>
🦋 Changeset detectedLatest commit: f7d2413 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@arkenv/agent-plugin
arkenv
@arkenv/build
@arkenv/bun-plugin
@arkenv/core
@arkenv/fumadocs-ui
@arkenv/nextjs
@arkenv/nuxt
@arkenv/standard
@arkenv/vite-plugin
commit: |
There was a problem hiding this comment.
ℹ️ No critical issues — two minor suggestions inline.
Reviewed changes
arkenv synccommand: a newSyncUseCasethat locates the schema (reusing the extractedresolveSchemaPath), imports it via the Jiti loader, and writes a merge-aware.env.examplewithcreated/updated/unchangedstatus and--jsonsettlement envelopes.merge-env-examplefeature: a block parser that attaches comment/blank preludes to their key, preserves surviving keys/values/comments in file order, drops stale keys, and appends new keys in declaration order. Covered by a focused unit test suite.- CLI wiring:
syncInputincli.ts,composition.tsinjectsSyncUseCaseintoInitUseCase,help/meta.jsonentries,bin.tsdispatch, and the flag-position handling forcheck/sync. checkrefactor:resolveSchemaPathmoved intofeatures/schema-loader/and reused bycheck, removing a private duplicated method.- Docs/changeset: new
sync.mdx, reference index/meta.jsoncards,CONTEXT.md/ARCHITECTURE.mdentries, and aminorchangeset.
The merge algorithm is sound — blocks attach leading comments to their assignment, surviving keys stay in file order so the merge is idempotent, and deduplication keeps "already in sync" runs stable. The re-run test correctly pins that the second run writes nothing and reports unchanged.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
Keep sync's .env.example wording and v1's .arkenv codegen paths. Co-authored-by: Cursor <cursoragent@cursor.com>
Preserve an existing .env.example trailing-newline style and drop unused --yes from sync input. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
- Trailing-newline idempotency fix:
mergeEnvExamplenow derivestrailingNewlinefrom the existing file (content.endsWith("\n")) instead of forcing one for any non-empty output, so a matching.env.examplewithout a final newline staysunchangedon the firstsync. The new regression test pins this and genuinely fails on the old logic. Thecontent === existingequality check keeps the merge idempotent. - Dropped dead
isYes: removed fromSyncInputandsyncInput—SyncUseCase.executenever consulted it, so a passed--yeswas silently ignored.
Both findings from the prior review are addressed correctly. The delta introduces no new issues — the newline change is covered by a real regression test and holds for created/updated/unchanged paths.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
Record why example beats sync so the verb stays free for a later job. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
arkenv sync: generate/update .env.example from the env schemaarkenv example: update .env.example from the env schema
There was a problem hiding this comment.
Caution
This PR no longer builds. Commit ccae9c47 ("refactor: rename sync command files to example") renamed the source files but updated none of the references that point at them, leaving 5+ unresolved imports and the whole arkenv package uncompilable. CI is already red on this head (test-build, test, test-typesafety, e2e, pkg-pr-new, and the vite-compat matrix all fail).
Reviewed changes
- Renamed
commands/sync.ts→commands/example.ts,features/sync/→features/example/, andsync.mdx→example.mdx(pure rename — 0 insertions) without touching any of the identifiers, imports, CLI routing, help text, or docs that reference the old names.
🚨 Rename is half-applied — the package does not compile
The rename moved the files but left every reference pointing at the deleted paths, so module resolution breaks and commands no longer exports SyncUseCase:
index.ts:5—export * from "./sync"(no such file) → breakscomposition.ts'simport { SyncUseCase } from "./commands".cli.ts:10— imports./commands/sync;init.ts:14— imports./sync;example.ts:3— imports@/features/sync/merge-env-example;example.test.ts:10— imports@/cli/commands/sync. All point at deleted paths.- Beyond imports, the CLI surface never changed:
bin.ts:53dispatches the keysync,cli.ts:155/315routessync/syncInput,example.tsstill emitscommandId: "sync"and aDOCS_URLpointing at/docs/reference/sync, and help/meta.jsonstill saysync. - Docs were left dangling: every reference card (
check.mdx:168,index.mdx:33,init.mdx:142) points to/docs/reference/sync, which no longer exists aftersync.mdx→example.mdx(would 404).example.mdx:2still has frontmattertitle: sync. The changeset.changeset/arkenv-sync.md,CONTEXT.md's Sync term, andARCHITECTURE.md'ssync/feature note all still documentsync.
Technical details
# Finish (or revert) the `sync` → `example` rename
## Affected sites
- packages/arkenv/src/cli/commands/index.ts:5 — `export * from "./sync"` is a dead import
- packages/arkenv/src/cli/commands/example.ts:3 — imports `@/features/sync/merge-env-example`, but the dir is now `features/example/`
- packages/arkenv/src/cli/commands/init.ts:14 — imports `SyncUseCase` from `./sync` (gone)
- packages/arkenv/src/cli/cli.ts:10,155,315 — import, command route, and `syncInput` getter persisted as `sync`
- packages/arkenv/src/cli/commands/example.test.ts:10 — test imports `@/cli/commands/sync`
- packages/arkenv/src/bin.ts:53 — dispatch key `sync`
- apps/www/content/docs/reference/example.mdx — `title: sync` frontmatter; body/`commandId: "sync"`
- apps/www/content/docs/reference/{check,index,init}.mdx and meta.json — Cards / `"sync"` entry / URLs
- .changeset/arkenv-sync.md; docs/CONTEXT.md ("Sync" term); docs/ARCHITECTURE.md (`sync/` tree entry)
## Required outcome
The branch must typecheck, build, and pass CI. The public command name must be consistent
across implementation and every surface, and match the design doc's chosen story
(`docs/design/cli-env-example-command-name.md` chose `arkenv example`) — or revert back to
`sync` if that's preferred. Either direction is valid; a mix is not.
## Suggested approach
Per the design-doc lean (`arkenv example`): complete the rename across all surfaces — fix the
five imports (and rename `SyncUseCase`/`SyncInput` or keep as internal names), route the CLI
key + positional validation from `sync` → `example`, update `commandId: "example"` and
`DOCS_URL` → `/docs/reference/example`, retitle `example.mdx`, delete the stale `sync` cards
and the `meta.json` entry, and rewrite the changeset. If the intent was instead to keep
`sync` public, the clean fix is to revert `ccae9c47` entirely.
## Open questions for the human
Is the public name `arkenv example` (per the design doc) or stay `sync`? Settle before merge.DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
The file move left imports, dispatch, help, and docs still pointing at sync, which broke CI. Wire the public command to arkenv example with no alias. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
- Rename
sync→examplecompleted across every surface: the half-appliedccae9c47rename (which broke the build) is now finished —SyncUseCase/SyncInputbecameExampleUseCase/ExampleInput, the CLI routes and dispatchesexample, positional validation accepts it,commandIdis"example",DOCS_URLpoints at/docs/reference/example, and help output,meta.json, the changeset, ADR 0027,CONTEXT.md, andARCHITECTURE.mdall sayexample, with zero stalesyncreferences left in source or docs. arkenv initplumbing updated:InitUseCasenow holds an optionalExampleUseCaseand reuses it to seed.env.examplefor existing projects; its warning copy instructs users to runarkenv example.- Success-message reworded:
.env.example already matches the schemareplaces "is already in sync with the schema", with the corresponding JSON and text assertions updated to match.
Verified this run: pnpm exec turbo run typecheck --filter=arkenv passes (5 tasks), the full arkenv suite is green (461 tests / 27 files), and CI on this head is green across test, test-build, test-typesafety, e2e, pkg-pr-new, the vite-compat matrix, and autofix. The prior CRITICAL finding is fully addressed.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Fixes #1234
Summary
arkenv exampleto load the project schema (same discovery and loader ascheck) and write merge-aware.env.example(preserve comments/values, drop stale keys, append new keys).arkenv initafter scaffolding an existing project.examplewith nosyncalias, sosync/generatestay free for later commands. Help one-liner: Update.env.examplefrom the schema.--jsoncreated/updated/unchanged envelopes.Test plan
pnpm run typecheckpnpm run test -- --runpnpm run fixarkenv examplein a fixture withenv.tsand no.env.example