This document translates the product-level spec in SPEC.md into an implementation plan for the ever-cli repository.
It is intended for review before coding begins.
The goal is to clarify:
- what problem
ever-cliis solving - how it relates to product CLIs such as
ever-works-cli - what should be implemented in this repository
- what the MVP must include
- what should be deferred to later phases
ever-cli is no longer meant to be a product-specific TypeScript CLI.
It is meant to become the root Ever ecosystem router:
ever <product> <command> [args...]Examples:
ever works init
ever cloc start timer
ever os run agentsThe router itself must stay small. It should:
- recognize a small set of built-in commands
- resolve product CLIs such as
ever-works,ever-cloc,ever-os - forward all remaining arguments to the resolved product binary
- maintain local installation/discovery metadata
- provide a clear install and diagnostic experience
The router must not contain product business logic.
Product logic remains inside standalone CLIs such as:
ever-works-cliever-cloc-cliever-os-cliever-gauzy-cli
This task is related to Ever Works, but it should not be implemented inside the Ever Works monorepo applications.
The connection is:
ever-works-cliis one of the product CLIs the router must support- Ever Works has both public and internal CLIs
- this router targets the public CLI surface only
Therefore:
- implementation target:
ever-cli - integration target for testing:
ever-works-cli - not in scope: moving this router into
apps/cliorapps/internal-cliinsideever-works
Current ever-cli state:
- repository: standalone npm package
- implementation: minimal TypeScript stub
- main entrypoint:
src/main.ts - behavior today: banner/logo output only
Current package state:
- package name:
ever-cli - bin:
ever -> ./dist/main.js - old Node/TS stack:
typescript,yargs,chalk,figlet,tslint
This means the current implementation does not match the target architecture in any meaningful way. The router should be treated as a replacement of the current runtime, not an incremental extension of the existing banner tool.
ever-cli becomes a thin router with these responsibilities:
- Parse the root command line
- Intercept built-in commands
- Resolve a product binary
- Replace the process with the resolved binary when routing
- Maintain local router metadata under
~/.ever/
Product resolution should follow the spec exactly:
- Manifest lookup:
~/.ever/plugins.json
- PATH fallback:
- binary name:
ever-<product>
- binary name:
- Not found:
- clear install guidance
Router-owned files:
~/.ever/
├── config.toml
├── plugins.json
└── cache/
For MVP, only these are required:
~/.ever/plugins.json- optional creation of
~/.ever/if missing
config.toml support can start minimal and expand later.
The router reserves these command names:
installuninstallupdatelistdoctorversionhelpconfig
For MVP, the first commands that should be truly implemented are:
helpversionlistdoctorinstall
uninstall, update, and config may begin as stubs if needed, but they should still be recognized as reserved router commands.
The router should be implemented in Rust.
Reasons:
- the product spec explicitly calls for Rust
- router startup cost should be minimal
- the router does very little but is invoked on every routed command
- the ecosystem pattern described in the spec matches common Rust CLI distribution through npm
Primary distribution should remain npm:
npm install -g ever-cliBut the runtime implementation is Rust.
This implies two layers:
- Rust router binary
- thin npm wrapper/distribution packaging
For MVP, the Rust router itself is the priority. Cross-platform npm packaging should be treated as a second phase unless explicitly requested in the first delivery.
Suggested first structure:
ever-cli/
├── Cargo.toml
├── src/
│ ├── main.rs
│ ├── cli.rs
│ ├── catalog.rs
│ ├── manifest.rs
│ ├── resolver.rs
│ ├── exec.rs
│ ├── fs.rs
│ ├── error.rs
│ └── commands/
│ ├── mod.rs
│ ├── help.rs
│ ├── version.rs
│ ├── list.rs
│ ├── doctor.rs
│ └── install.rs
└── docs/
├── SPEC.md
└── IMPLEMENTATION_SPEC.md
Keep dependencies conservative:
clapfor argument parsingserde+serde_jsonfor manifest serializationdirectoriesordirsfor home/config path discoverywhichfor PATH lookupthiserroror custom error enums for error handling
Use the Rust standard library for:
- process execution
- file existence checks
- environment access
The first implementation should produce a usable router, not the complete long-term ecosystem tooling.
- Rust entrypoint
- Router arg parsing
- Built-in command detection
- Manifest load/save
- PATH fallback for
ever-<product> - Exec forwarding to product CLI
- Static built-in product catalog
ever listever doctorever install <product>with npm-first installation flow
- auto-register discovered PATH binaries into manifest
- stale manifest entry recovery
- clear human-readable error messages
- product catalog entry for
works - local validation against
ever-works-cli
- full cargo install flow
- full GitHub release install flow
- remote catalog updates
- Homebrew / winget / curl installer
- optionalDependencies npm binary packaging matrix
- advanced config editing
- alias conflict remediation
- community plugin registry UX beyond basic future-compatible design
ever install <product> should be implemented in the simplest correct way first.
Recommended first behavior:
- resolve product from static catalog
- derive npm package name
- run:
npm install -g ever-<product>-cli- resolve installed binary path
- write manifest entry
- print success message
This should be npm-first only in MVP.
Cargo and GitHub sources can be added later behind:
--from cargo--from github
The router should ship with a static built-in catalog as described in the main spec.
For MVP, it is acceptable to:
- include the full static list from
SPEC.md, or - include a minimal initial list with at least:
worksclocosgauzy
Recommendation:
- include the full static list now
- it is simple data and avoids revisiting catalog shape immediately
Initial manifest structure should match the product spec:
{
"version": 1,
"plugins": {
"works": {
"binary": "/usr/local/bin/ever-works",
"package": "ever-works-cli",
"source": "npm",
"version": "0.5.0",
"installed_at": "2026-04-01T12:00:00Z"
}
}
}For MVP:
- missing optional fields may be tolerated internally
- persisted shape should remain compatible with the spec
On Unix/macOS:
- use true process replacement where possible
On Windows:
- use spawn/wait/exit-code propagation behavior appropriate to platform constraints
The goal is:
- correct stdout/stderr passthrough
- correct exit codes
- correct signal behavior
Even if Windows behavior differs internally, the user-facing behavior should remain consistent.
- approve this implementation spec
- confirm MVP scope
- confirm whether npm-first install is sufficient for first PR
- initialize Rust project
- replace current TS runtime with Rust entrypoint
- implement built-in command parsing
- implement manifest support
- implement PATH resolution
- implement routing exec flow
- implement
help - implement
version - implement
list - implement
doctor - implement npm-first
install
- test with installed
ever-works-cli - validate:
ever works --helpever works init- manifest discovery
- PATH fallback
- add npm wrapper strategy for native binary distribution
- prepare platform package approach
- define release workflow
This should be a separate step unless it is explicitly required in the first implementation PR.
The spec describes npm, cargo, and GitHub installs. Implementing all three at once increases complexity and testing burden.
Recommendation:
- ship npm-first install in MVP
- keep source abstraction in the code design so cargo/github can be added cleanly later
The root router handles:
ever works ...
Short aliases such as:
works ...cloc ...
are primarily the responsibility of each sub-CLI package and its installation method.
The router should be aware of alias conflicts for doctor, but it should not block MVP routing work.
The Rust router can and should be built first even if cross-platform npm publishing is not ready yet.
This separates:
- runtime correctness
- distribution engineering
The current src/main.ts is too small and too far from the target architecture to be treated as a meaningful foundation.
The implementation should optimize for the target router design, not for preserving the existing stub structure.
The first implementation should be considered acceptable when the following work:
ever --help
ever version
ever list
ever doctorAssuming ever-works-cli is installed:
ever works --help
ever works initever install worksExpected result:
- installs
ever-works-cli - resolves
ever-works - writes manifest entry
ever works --helpworks afterward
If a manifest path is stale but ever-works exists elsewhere on PATH:
- router should discover it
- update manifest
- continue successfully
This document does not define:
- exact Rust crate versions
- exact CI YAML for release matrix
- exact npm package publishing automation
- final Windows packaging details
Those belong to implementation PRs once the architecture is approved.
First PR target:
- Rust router core
- manifest + PATH resolution
- npm-first install
- basic built-ins
- validation against
ever-works-cli
This gives a usable vertical slice quickly while preserving the architecture required by the product spec.