HarperFast / HarperFast/harper
First-class install flags so install.command isn't the only lever
- Dominant language
- JavaScript
- Stars
- 89
- Forks
- 10
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 200
Description
## Summary
There is no way to adjust a component install short of replacing the entire invocation. Common, routine adjustments — most obviously "don't install devDependencies" — require setting `install.command`, which discards `--ignore-scripts`, the `devEngines.packageManager` resolution, and `applications_packageManagerPrefix` along with it.
So the escape hatch is the *only* lever, and every small adjustment forces a large, control-bypassing one.
## Evidence the flags are already wanted
The deprecated `install_node_modules` operation already passes `--omit=dev` (`utility/npmUtilities.ts:45`):
```js
const args = ['install', '--force', '--omit=dev', '--json'];
```
…while the actual deploy path (`components/Application.ts:424`) does not:
```js
const npmInstallArgs = application.install?.allowInstallScripts
? ['install', '--force']
: ['install', '--force', '--ignore-scripts'];
```
The flag is desired; it's just applied in a deprecated code path and not the live one. A component deployed normally gets its devDependencies installed.
## Proposal
Structured options for the common flags — `omit`, `preferOffline`, `noAudit`, `noFund` — plus an `extraArgs: string[]` pressure valve. The important property is that these **compose** with `--ignore-scripts`, the package-manager resolution, and the prefix, rather than replacing them the way `install.command` does.
**Boundary rule**, stated up front because this is the proposal most exposed to scope creep: expose only flags that are (a) meaningful across npm/yarn/pnpm, since all three are reachable via `devEngines.packageManager`, and (b) about *what* gets installed or *how* it is fetched. Anything else keeps using `install.command`. `extraArgs` covers the tail without turning this into an arbitrary passthrough surface.
The creep matters in both directions: if this doesn't cover real use cases, `install.command` stays mandatory and hardening it stays unpalatable.
## Open question
**Should `--omit=dev` be the default for component installs?** Shipping devDependencies to a deployed component is rarely intended, and it's what the deprecated operation already does. But it's a behavior change — a component that currently resolves a devDependency at runtime would start failing. Probably wants a minor version and a release note rather than a patch.
Also worth deciding: whether these are operator-level (global config) or component-author-level (per-app `install` block), or both. The existing `install` block is component-author-settable and already carries `allowInstallScripts`, so there's a precedent for author control — but "what gets installed on my host" has an operator flavor too.
Related: #1974 — note that any lifecycle option added here won't take effect for payload-deployed components until they're redeployed, since those never re-enter the install path.
---
🤖 Filed by Claude on behalf of @heskew
Contributor guide
Research direction
Start by reading components/Application.ts around the install argument construction and utility/npmUtilities.ts for the deprecated flags. Trace the existing install block and package-manager resolution, then determine the option shape, scope, and compatibility behavior before implementation. Done means the proposal is settled and structured flags compose with existing install behavior without requiring install.command.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nodejs
- Domain
- backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100