morphix-env 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,281 +1,155 @@
1
1
  <p align="center">
2
+
3
+ [本仓文档入口](./docs/README.md) · [本地工程约定](./docs/engineering.md)
2
4
  <img src="docs/logo.png" width="160" alt="morphix-env" />
3
5
  </p>
4
6
 
5
7
  # morphix-env
6
8
 
7
- `morphix-env` is a secret composition CLI for local development, CI, and agent-assisted workflows. It does not become another secret vault: Infisical, Doppler, macOS Keychain, dotenvx, and local files continue to own their values, authentication, access controls, rotation, and provider UI.
8
-
9
- `morphix-env` assembles the sources chosen by a profile into one short-lived child-process environment, records value-free provenance, and keeps normal command output, inspection, audit records, and generated workflow guidance free of secret values.
10
-
11
- The concise command is `mx-env`; the published `morphix-env` command remains fully supported.
12
-
13
- The package also ships a maintained, value-free Agent Skill (`mx-env skill install`) so agents can adopt the whole workflow — safety rules, configuration schema, commands — without a second distribution; see [Agent workflow](#agent-workflow).
9
+ A secret composition CLI for local development, CI, and agent-assisted workflows. It is not another vault: Infisical, Doppler, macOS Keychain, dotenvx, and local files keep owning their values — `mx-env` composes the sources a profile selects into one short-lived child-process environment and keeps inspection, audit, and editor output free of secret values.
14
10
 
15
- ## Quick start: global local defaults
11
+ ## Quick start
16
12
 
17
- Create this file once:
18
-
19
- ```dotenv
20
- # ~/.mx-env/.env
21
- PERSONAL_API_URL=http://localhost:4444
22
- ```
23
-
24
- Protect it on macOS/Linux:
13
+ **With an Agent (recommended):** install the packaged skill, commit it, and let the agent do the rest. The skill carries the safety rules, the full configuration schema, onboarding steps, and troubleshooting — so this README does not have to:
25
14
 
26
15
  ```bash
27
- mkdir -p ~/.mx-env
28
- chmod 700 ~/.mx-env
29
- chmod 600 ~/.mx-env/.env
16
+ npx morphix-env@latest skill install --target project # writes .claude/skills/morphix-env/ — commit it with the repo
30
17
  ```
31
18
 
32
- Then every normal project command can use it without repeating configuration:
19
+ Then tell your agent something like "set up this project's environment with mx-env". The agent reads the skill and drives configuration, validation, and editing; nobody pastes a secret value into chat.
33
20
 
34
- ```bash
35
- mx-env run -- pnpm dev
36
- ```
37
-
38
- `~/.mx-env/.env` is deliberately the only automatically discovered value file. `~/.mx-env/config.json` is optional and adds global Keychain, encrypted-file, or remote-provider sources. For CI, investigation, or an unfamiliar repository, use a reproducible project-only run:
21
+ **Without an Agent:**
39
22
 
40
23
  ```bash
41
- mx-env run --no-global -- pnpm dev
24
+ npm install -g morphix-env
25
+ mx-env run -- pnpm dev # compose the project profile and run
26
+ mx-env inspect # key names, sources, status — never values
42
27
  ```
43
28
 
44
- ## Source precedence and conflicts
29
+ Optionally create `~/.mx-env/.env` (chmod 600) for personal machine-wide defaults; they join every run at low precedence unless `--no-global`.
45
30
 
46
- The composed environment has a fixed low-to-high order:
31
+ ## How it works
32
+
33
+ A profile lists sources from low to high; the composed environment follows a fixed baseline:
47
34
 
48
35
  ```text
49
36
  inherited process.env
50
37
  → ~/.mx-env/.env
51
- → ~/.mx-env/config.json default profile
52
- → project profile or legacy project configuration
53
- → explicit CLI local override (-f)
38
+ → global default profile
39
+ → project profile (or legacy Infisical config)
40
+ → explicit -f override file
54
41
  ```
55
42
 
56
- Two sources that provide the same key fail by default. The later source must explicitly declare `"override": true` to replace the earlier value. This catches accidental cross-environment collisions instead of silently selecting a database, API, or deployment credential.
57
-
58
- Existing projects remain compatible: a legacy `mx-env.config.json` still composes the configured Infisical paths followed by `.env.local`, so `.env.local` remains the deliberate override layer.
59
-
60
- ## Profiles and providers
61
-
62
- Profiles compose complete source collections; do not enumerate every secret in repository configuration.
63
-
64
- ```jsonc
65
- // ~/.mx-env/config.json — optional user baseline, never contains values
66
- {
67
- "sources": {
68
- "machine-keychain": {
69
- "provider": "os-keychain",
70
- "platform": "macos",
71
- "service": "com.morphix.env/global"
72
- },
73
- "team-defaults": {
74
- "provider": "infisical",
75
- "paths": ["/shared"]
76
- }
77
- },
78
- "profiles": {
79
- "developer-default": {
80
- "sources": ["machine-keychain", "team-defaults"]
81
- }
82
- },
83
- "defaultProfile": "developer-default"
84
- }
85
- ```
43
+ The same key from two sources fails by default; the later source must declare `"override": true` to replace the earlier value. Configuration never contains values — only wiring:
86
44
 
87
45
  ```jsonc
88
46
  // project/mx-env.config.json
89
47
  {
90
48
  "sources": {
91
- "api": {
92
- "provider": "infisical",
93
- "paths": ["/ai/api"]
94
- },
95
- "project-doppler": {
96
- "provider": "doppler",
97
- "project": "morphicai-api",
98
- "config": "dev"
99
- },
100
- "local": {
101
- "provider": "local",
102
- "files": [".env.local"],
103
- "override": true
104
- }
105
- },
106
- "profiles": {
107
- "api-dev": {
108
- "extends": "developer-default",
109
- "sources": ["api", "project-doppler", "local"]
110
- }
49
+ "team": { "provider": "infisical", "paths": ["/ai/api"] },
50
+ "doppler": { "provider": "doppler", "project": "morphicai-api", "config": "dev" },
51
+ "local": { "provider": "local", "files": [".env.local"], "optional": true, "override": true }
111
52
  },
112
- "defaultProfile": "api-dev"
53
+ "profiles": { "dev": { "sources": ["team", "doppler", "local"] } },
54
+ "defaultProfile": "dev"
113
55
  }
114
56
  ```
115
57
 
116
- Run it with either CLI name:
58
+ Providers: `infisical` · `doppler` · `os-keychain` (macOS) · `dotenvx` (encrypted files) · `local` (dotenv files). Provider login and bootstrap stay on the provider side (`infisical login`, `doppler login`, dotenvx key bootstrap) and never enter repository config.
117
59
 
118
- ```bash
119
- mx-env run --profile api-dev -- pnpm dev
120
- morphix-env run --profile api-dev -- pnpm dev
121
- ```
60
+ ## Compared with existing secret management
122
61
 
123
- ### Supported sources
62
+ `morphix-env` is a composition layer, not a fifth vault:
124
63
 
125
- | Provider | Source selector | Value ownership / bootstrap |
126
- |---|---|---|
127
- | `infisical` | `paths`, optional project/site/environment settings | Local: `infisical login`. CI: Machine Identity through the usual `INFISICAL_CLIENT_ID`, `INFISICAL_CLIENT_SECRET`, and project identity flow. Do not put these in project config. |
128
- | `doppler` | `project` and `config` | Local: `doppler login`. CI: a least-privilege Doppler Service Token supplied outside repository configuration, ideally via workload identity or the OS Keychain. |
129
- | `os-keychain` | macOS generic-password `service`; each account is an environment key | macOS only in this release. Keychain owns the value; use `mx-env edit` to add/update it. |
130
- | `dotenvx` | encrypted `files` | Install `dotenvx` separately and provide its private decryption key through a secure bootstrap path. The encrypted file stays provider-managed. |
131
- | `local` | dotenv `files` | Intended for project `.env.local` and explicitly declared user files. A missing source is only allowed with `"optional": true`. |
64
+ | | dotenv / direnv | dotenvx | Infisical / Doppler CLI | 1Password CLI / Vault | morphix-env |
65
+ |---|---|---|---|---|---|
66
+ | Values live in | plaintext local files | encrypted local files | provider cloud | the vault | **nowhere new** — every system above stays the value owner |
67
+ | Composing multiple sources | ✗ | ✗ | own product only | own product only | ✓ one profile mixes any of them, plus a global baseline |
68
+ | Same-key collision | silently shadowed | silently shadowed | n/a | n/a | hard error unless an explicit `"override": true` |
69
+ | Agent context hygiene | `cat .env` leaks | partial | `secrets --plain` leaks | `op read` leaks | inspect / audit / editor are value-free; `run` redacts injected values from child output |
132
70
 
133
- ### Doppler compared with Infisical
71
+ Choosing between Infisical and Doppler still depends on each provider's own identity, audit, rotation, and pricing — `morphix-env` does not replace that decision. It composes whichever you already use (or several, plus local sources) behind one stable `mx-env run --profile` interface.
134
72
 
135
- Both are strong team secret managers; `morphix-env` treats them as sources rather than attempting to reproduce their control planes.
73
+ ## Value safety
136
74
 
137
- | Concern | Infisical | Doppler | What `morphix-env` adds |
138
- |---|---|---|---|
139
- | Organization | projects, environments, folders/paths, identities | project, config, root/branch config inheritance | One profile can combine either or both with local sources. |
140
- | Local execution | SDK Machine Identity or `infisical` CLI | `doppler login` + `doppler run` | One stable `mx-env run --profile` interface. |
141
- | CI least privilege | Machine Identity scoped by project/path/role | Service Token scoped to project/config | Provider bootstrap stays outside config; profile decides only which source is requested. |
142
- | Visual value editing | Provider dashboard | Provider dashboard | `mx-env edit` opens provider-owned routes instead of copying values into a new dashboard. |
143
- | Local Keychain / global dotenv | Not their primary concern | Not their primary concern | `~/.mx-env` and `os-keychain` participate in the same explicit order. |
75
+ - `mx-env inspect` reports key names, source provenance, and configured state only.
76
+ - `mx-env edit --profile <name>` opens a short-lived, loopback-only browser editor: remote sources route to their provider-owned UI, Keychain never reveals existing values, and on macOS the one-time editor URL is not printed to the terminal unless `--print-editor-url`.
77
+ - `mx-env run` is the only injection path. Exact injected values are redacted from forwarded child output, including across stream chunks; browser-public prefixes (`NEXT_PUBLIC_`, `VITE_`, `EXPO_PUBLIC_`) are a deliberate exception.
78
+ - Audit events carry profile/source/key names, outcome, and exit code — never values, command arguments, or provider stderr.
144
79
 
145
- Choose a provider based on its own identity, audit, rotation, price, and hosting requirements. Provider switching is not assumed to be a one-line operation: source selectors and permissions remain provider-specific even though the consuming command remains stable.
80
+ This is leakage minimization, not a cryptographic boundary: a process that receives a secret can still transform or exfiltrate it deliberately. For a high-risk agent capability, use a provider proxy/broker as a separate security design rather than passing that credential through `run`.
146
81
 
147
- For a manual Doppler smoke test, authenticate with `doppler login`, declare a non-production project/config source, and run `mx-env inspect --profile <profile>`. It must report the Doppler source and key names only. Use `mx-env run --profile <profile> -- <non-echoing command>` to validate delivery; do not use `doppler secrets get --plain` or print the child environment.
82
+ ## On-demand secrets with `run --serve`
148
83
 
149
- ## Visual editor
84
+ `mx-env run --serve -- <command>` (modeled on aws-vault's `--ecs-server`) starts a loopback HTTP server on 127.0.0.1 at a random port that shares the child's lifetime:
150
85
 
151
- Use the one-shot editor instead of asking someone to paste a value into chat:
86
+ - Composed non-public values never enter the child environment — not the direct child, its descendants, `/proc/<pid>/environ`, or core dumps. The child receives only `MXENV_ENDPOINT` and a random `MXENV_TOKEN`, and the token is redacted from child output like any injected value. Honest caveat on token visibility: an environment-delivered capability token is readable by same-uid processes on Linux via the child's `/proc/<pid>/environ` — the same inherent property as aws-vault's `--ecs-server`; the *values* themselves still appear in no process environment anywhere.
87
+ - The child fetches one value at a time: `mx-env fetch <KEY>` (thin client that reads endpoint/token from its own environment and prints the exact value with no trailing newline), or a direct `GET /key/<KEY>` with `Authorization: Bearer $MXENV_TOKEN`. The endpoint answers 401 without the token and 404 for unknown keys; no request or value is ever logged.
88
+ - Browser-public keys (`NEXT_PUBLIC_`, `VITE_`, `EXPO_PUBLIC_`) stay in the environment so build tools can inline them; they remain servable as well.
89
+ - The server is destroyed the moment the child exits (and dies with the parent process itself), so no listener outlives the run.
152
90
 
153
- ```bash
154
- mx-env edit --profile api-dev
155
- mx-env edit --source machine-keychain
156
- ```
91
+ `mx-env run` without `--serve` is unchanged: values are injected into the environment and redacted from forwarded output.
157
92
 
158
- It starts a short-lived loopback-only browser session. The profile page shows names, source precedence, configured state, provenance, and collisions without values.
93
+ ## Provider plugins
159
94
 
160
- - Infisical and Doppler sources route the user to their provider-owned editor.
161
- - Local dotenv files can be edited only in the selected local source.
162
- - Keychain shows account names but never reveals existing values; it can add or update an account value.
163
- - dotenvx writes through its CLI so it remains responsible for the encrypted representation.
95
+ Any executable on PATH named `mx-env-provider-<name>` is a provider — new remote stores need no changes to `config.ts` / `sources.ts` / `editor.ts`:
164
96
 
165
- The CLI prints status only, never a secret value.
166
-
167
- On macOS the browser opens automatically and the default CLI output intentionally omits the one-time editor URL, so an Agent tool result does not receive a bearer-like local session capability. A human can explicitly request the URL when needed:
168
-
169
- ```bash
170
- mx-env edit --profile api-dev --print-editor-url
171
- ```
172
-
173
- On macOS, verify Keychain editing manually after installing a new version: use a temporary `os-keychain` service namespace, run `mx-env edit --source <name>`, add a generated test account in the browser, confirm it appears in the account-name list without revealing its value, then use **Delete** to remove it. The terminal transcript must contain only the editor URL/status.
174
-
175
- ## Context hygiene
176
-
177
- ```bash
178
- mx-env inspect --profile api-dev
179
- mx-env audit tail
97
+ ```jsonc
98
+ // mx-env.config.json
99
+ {
100
+ "sources": {
101
+ "vault": { "provider": "plugin", "plugin": "bitwarden", "keys": ["OPENAI_API_KEY"] }
102
+ }
103
+ }
180
104
  ```
181
105
 
182
- `inspect` lists key names, source provenance, and configured state only. Audit events contain profile/source/key names, outcome, duration, and exit code—never a value, value prefix, command arguments, or provider stderr.
183
-
184
- When child output is forwarded through the CLI, exact non-public injected values are redacted as `[REDACTED]`, including when the value crosses stream chunks or the command fails.
106
+ Plugin protocol (summon-style):
185
107
 
186
- This is leakage minimization, not a cryptographic isolation boundary. A process that receives an environment variable can deliberately transform or exfiltrate it. For a high-risk Agent capability, use a provider proxy/broker as a separate security design rather than passing that credential through `run`.
108
+ - Invoked as `mx-env-provider-<plugin> <KEY>`, once per declared key; exit 0 with the value on stdout (one trailing line ending stripped).
109
+ - A non-zero exit or a missing executable fails the source with a value-free error — the plugin's stderr is never surfaced because it may contain sensitive material. `optional: true` downgrades a missing executable to `missing-optional`.
110
+ - Plugins intentionally inherit the already-composed environment at their precedence position (inherited env → global baseline → profile sources loaded so far), so wrapper scripts can authenticate to their own backend without a second credential channel. Least-privilege consequence: a plugin can read every value composed before it — declare plugin sources only after the sources they need and keep each `keys` list minimal. Each key invocation times out after 30s.
111
+ - Login and bootstrap stay inside the plugin; repository config carries only wiring (plugin name + key names), never values.
187
112
 
188
- Browser variables (`NEXT_PUBLIC_`, `VITE_`, `EXPO_PUBLIC_`) are an intentional exception: they are public configuration, not protected secrets.
113
+ The five built-in providers (`infisical`, `doppler`, `os-keychain`, `dotenvx`, `local`) are unchanged.
189
114
 
190
115
  ## Commands
191
116
 
192
117
  ```bash
193
- # Run one command with its composed profile
194
- mx-env run --profile api-dev -- pnpm dev
195
-
196
- # Existing scripts remain valid
197
- morphix-env run --env dev -- pnpm dev
198
-
199
- # Generate public browser runtime configuration
200
- mx-env generate --profile api-dev --out public/__env.js
201
-
202
- # Value-free status/provenance
203
- mx-env inspect --profile api-dev
204
-
205
- # Open the short-lived visual editor
206
- mx-env edit --profile api-dev
207
-
208
- # Generate this project's value-free Agent workflow Skill
209
- mx-env doc --profile api-dev
210
-
211
- # Install the packaged Agent Skill (global | project | trellis)
212
- mx-env skill install --target project
213
-
214
- # Show per-target install state and template drift
215
- mx-env skill show
216
-
217
- # Value-free audit events
218
- mx-env audit tail
118
+ mx-env run --profile dev -- <command> # compose and run (the only injection path)
119
+ mx-env run --serve -- <command> # serve values over loopback instead of injecting them into env
120
+ mx-env fetch <KEY> # read one value from a run --serve child environment
121
+ mx-env export [--profile agents] # eval-able export KEY='value' lines (values in stdout only for eval)
122
+ mx-env render <template> <output> # substitute ${VAR} into a config file (mode 0600)
123
+ mx-env inject <template> <output> # resolve mx-env://profile/KEY references into a file (mode 0600)
124
+ mx-env inspect [--profile dev] # key names + provenance, no values
125
+ mx-env edit [--profile dev | --source s] # one-shot visual editor
126
+ mx-env generate --out public/__env.js # public browser runtime config
127
+ mx-env doc # write this project's key→source skill
128
+ mx-env skill install | show # packaged Agent Skill (global / project / trellis)
129
+ mx-env audit tail # value-free audit events
219
130
  ```
220
131
 
221
- Options:
222
-
223
- | Option | Meaning |
224
- |---|---|
225
- | `-p, --profile <name>` | Select a named profile. |
226
- | `-f, --env-file <path>` | Append a local override source for this invocation. |
227
- | `-e, --env <name>` | Override the Infisical environment for selected Infisical sources. |
228
- | `--no-infisical` | Skip Infisical sources. |
229
- | `--no-global` | Ignore `~/.mx-env/.env` and `~/.mx-env/config.json`. |
230
- | `--allow-insecure-global` | Explicitly permit a global dotenv file readable by group/other users. Avoid this outside controlled troubleshooting. |
231
- | `--print-editor-url` | Explicitly print the one-time local editor URL; normally the browser opens without emitting it to the terminal. |
232
- | `--target <scope>` | `skill install` destination: `global` (`~/.claude/skills/`), `project` (`.claude/skills/` inside the repo — commit it), or `trellis` (`~/.trellis/skills/` canonical store). |
233
- | `--force` | Replace an installed skill that differs from this version's template; a modified file is never overwritten without it. |
234
- | `-o, --out <path>` / `--filter <prefix>` | Configure public browser-env generation. |
235
- | `-v, --verbose` | Show source state and key counts, not values. |
132
+ `export`, `render`, `inject`, and `run` accept `--dry-run` (key/variable names only, never values). `eval "$(mx-env export --profile agents)"` injects a profile into the current shell without putting values in shell history. `render` and `inject` write mode-0600 outputs, warn about unresolved `${VAR}` / `mx-env://` references before writing, and warn when the output path is not git-ignored. `mx-env://profile/KEY` references (mirroring 1Password's `op://`) let MCP configs and dotenv templates stay in git without values: `mx-env inject` resolves them at the file level, `mx-env run` resolves them inside composed values before spawning.
236
133
 
237
- ## Agent workflow
134
+ Full options live in `mx-env --help`; the packaged skill mirrors the commands of the installed version.
238
135
 
239
- ### Packaged Agent Skill
136
+ ## Agent workflow
240
137
 
241
- The npm package ships a maintained, value-free Agent Skill at `dist/SKILL.md`. It teaches an agent the full workflow: safety red lines (inspect for validation, `edit` for changes, `run` as the only injection path), the complete `mx-env.config.json` schema for all five providers, a command cheatsheet, project onboarding steps, and troubleshooting. Because it travels with the CLI, it always documents commands that exist in the installed version.
138
+ The npm package ships a maintained, value-free Agent Skill (`dist/SKILL.md`) so agents adopt the whole workflow — safety red lines, the complete schema for all five providers, a command cheatsheet, project onboarding, troubleshooting — without a second distribution:
242
139
 
243
140
  ```bash
244
- # Agent bootstrap straight from npm — no global install required
245
- npx morphix-env@latest skill install --target project
246
-
247
- mx-env skill install --target project # <repo>/.claude/skills/morphix-env/SKILL.md — commit it with the repository
248
- mx-env skill install --target global # ~/.claude/skills/morphix-env/SKILL.md — every project on this machine
249
- mx-env skill install --target trellis # ~/.trellis/skills/morphix-env/SKILL.md — then `trellis sync skills`
141
+ mx-env skill install --target project # <repo>/.claude/skills/morphix-env/ — commit it with the repo
142
+ mx-env skill install --target global # ~/.claude/skills/morphix-env/ — every project on this machine
143
+ mx-env skill install --target trellis # ~/.trellis/skills/morphix-env/ — then `trellis sync skills`
250
144
  ```
251
145
 
252
- Installs are idempotent: a re-run against an unchanged template is a no-op, and a skill file the user has customized is never overwritten without `--force`. `mx-env skill show` reports each target's install state and whether it still matches the shipped template.
253
-
254
- ### Project workflow Skill
146
+ Installs are idempotent, and a skill file the user has customized is never overwritten without `--force`. `mx-env skill show` reports each target's install state and template drift.
255
147
 
256
- `mx-env doc --profile <profile>` writes a value-free workflow Skill to `.agents/skills/morphix-env/SKILL.md` by default, listing this project's resolved key names and their winning sources. Generated or maintained Skills contain this rule:
257
-
258
- ```md
259
- When the user asks to add, modify, or rotate a credential:
260
- 1. Run `mx-env edit --profile <profile>` or `mx-env edit --source <source>`.
261
- 2. Let the user complete the edit in the local visual editor or provider UI.
262
- 3. Do not request the value in chat; do not run env, printenv, cat .env, or a reveal command.
263
- 4. Validate only configured status and provenance, never the value.
264
- ```
148
+ For project-specific guidance, `mx-env doc --profile <name>` generates a value-free skill listing this project's resolved key names and their winning sources (`.agents/skills/morphix-env/SKILL.md`).
265
149
 
266
150
  ## Legacy configuration
267
151
 
268
- This remains valid and needs no immediate migration:
269
-
270
- ```json
271
- {
272
- "infisical": { "paths": ["/ai"], "envPrefix": "VITE_" },
273
- "envFiles": [".env.local"],
274
- "generate": { "out": "public/__env.js", "filter": "NEXT_PUBLIC_" }
275
- }
276
- ```
277
-
278
- Migrate when a project needs named profiles, multiple providers, or a source that can be edited through the unified local entry point.
152
+ Existing `infisical` + `envFiles` config keeps working unchanged. Migrate to `sources` / `profiles` when a project needs named profiles, multiple providers, or a source editable through the unified entry point.
279
153
 
280
154
  ## License
281
155
 
package/dist/SKILL.md CHANGED
@@ -29,14 +29,15 @@ npx morphix-env@latest inspect # 免安装试用
29
29
  配置文件**不含任何值**,只声明 source 接线与组合顺序。项目级放仓库根 `mx-env.config.json`;用户级 `~/.mx-env/config.json` 可选(全局基线,`--no-global` 可排除)。`~/.mx-env/.env` 是唯一自动发现的值文件(个人默认值)。
30
30
 
31
31
  ```jsonc
32
- // 项目 mx-env.config.json — 五种 provider 全示例
32
+ // 项目 mx-env.config.json — 全部 provider 示例
33
33
  {
34
34
  "sources": {
35
35
  "local": { "provider": "local", "files": [".env.local"], "optional": true, "override": true },
36
36
  "encrypted": { "provider": "dotenvx", "files": [".env.shared"] },
37
37
  "keychain": { "provider": "os-keychain", "platform": "macos", "service": "com.example/myproject" },
38
38
  "infisical": { "provider": "infisical", "paths": ["/team/api"] },
39
- "doppler": { "provider": "doppler", "project": "my-project", "config": "dev" }
39
+ "doppler": { "provider": "doppler", "project": "my-project", "config": "dev" },
40
+ "plugin": { "provider": "plugin", "plugin": "bitwarden", "keys": ["OPENAI_API_KEY"] }
40
41
  },
41
42
  "profiles": {
42
43
  "dev": { "sources": ["keychain", "infisical", "local"] },
@@ -50,6 +51,7 @@ npx morphix-env@latest inspect # 免安装试用
50
51
 
51
52
  - profile 内 `sources` **从低到高**排列;同 key 冲突默认**报错**,靠后 source 显式 `"override": true` 才覆盖(防止两个环境的同名凭据静默错选)。
52
53
  - provider 登录与引导留在 provider 侧(`infisical login`、`doppler login`、dotenvx 解密密钥引导),**不写进项目配置**。
54
+ - plugin source:PATH 上的 `mx-env-provider-<name> <KEY>` 把值写到 stdout(退出码 0);插件自带登录,失败信息不含值。
53
55
  - 固定基线顺序:`inherited process.env → ~/.mx-env/.env → 全局默认 profile → 项目 profile / legacy 配置 → -f 覆盖文件`。legacy 项目(`infisical` + `envFiles` 字段)无需改动即兼容。
54
56
 
55
57
  ## 命令速查
@@ -57,6 +59,11 @@ npx morphix-env@latest inspect # 免安装试用
57
59
  ```bash
58
60
  mx-env run --profile dev -- <command> # 组合环境并执行(子进程输出脱敏)
59
61
  mx-env run --no-global -- <command> # 排除全局基线,可复现的项目-only 运行
62
+ mx-env run --serve -- <command> # 值不进 env:子进程经 MXENV_ENDPOINT/MXENV_TOKEN 按需取值
63
+ mx-env fetch KEY # 在 --serve 子进程内取单个值(精确输出,无换行)
64
+ mx-env export [--profile dev] # 输出可 eval 的 export KEY='value' 行(值只经 stdout 进入 eval)
65
+ mx-env render <tpl> <out> # 把 ${VAR} 渲染进不支持插值的配置文件(0600,缺变量先告警)
66
+ mx-env inject <tpl> <out> # 解析 mx-env://profile/KEY 引用(0600,MCP 配置入仓不落值)
60
67
  mx-env generate --out public/__env.js # 生成浏览器公开变量(NEXT_PUBLIC_/VITE_/EXPO_PUBLIC_ 属公开配置例外)
61
68
  mx-env inspect [--profile dev] # key 名 + source 归属 + 状态(无值)
62
69
  mx-env edit --profile dev | --source X # 一次性可视化编辑器(loopback + 15 分钟 TTL,保存后自动关闭)
@@ -66,6 +73,8 @@ mx-env skill install [--target global|project|trellis] [--force] # 安装本 S
66
73
  mx-env skill show # 查看各目标安装状态
67
74
  ```
68
75
 
76
+ `export` / `render` / `inject` / `run` 均支持 `--dry-run`(只报 key/变量名,不出值)。值永不出现在 shell 历史里:`eval "$(mx-env export --profile dev)"` 才是 export 的消费方式。
77
+
69
78
  ## 进入一个新项目的标准流程
70
79
 
71
80
  1. `mx-env inspect` — 看是否已有配置、哪些 key 已就绪;无配置时走 legacy `.env.local` / Infisical 兼容路径。