{"_id":"@buckeyestudio/toh-launch-environment","name":"@buckeyestudio/toh-launch-environment","dist-tags":{"next":"0.1.1-rc.2","latest":"0.1.1-rc.2"},"versions":{"0.1.1-rc.2":{"name":"@buckeyestudio/toh-launch-environment","description":"Immutable TheOpen Harness launch environment that records which layer supplied each value","version":"0.1.1-rc.2","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/dustinwloring1988/theopen-harness.git","directory":"packages/util/launch-environment"},"type":"module","main":"lib/index.js","types":"lib/types/index.d.ts","exports":{".":{"types":"./lib/types/index.d.ts","default":"./lib/index.js"},"./invariant":{"types":"./lib/types/invariant.d.ts","default":"./lib/invariant.js"},"./src/*":"./src/*","./package.json":"./package.json"},"license":"MIT","author":{"name":"buckeyestudio"},"peerDependencies":{"@buckeyestudio/toh-invariants":"^0.1.1-rc.2","@buckeyestudio/cordis":"^4.0.1"},"devDependencies":{"@buckeyestudio/toh-invariants":"^0.1.1-rc.2","@buckeyestudio/cordis":"^4.0.1"},"_id":"@buckeyestudio/toh-launch-environment@0.1.1-rc.2","bugs":{"url":"https://github.com/dustinwloring1988/theopen-harness/issues"},"homepage":"https://github.com/dustinwloring1988/theopen-harness#readme","_integrity":"sha512-DvvDmln9HL/JcwnDEKHIobviIQIkDjpdd3lpuwXOZv96iOkHj4ktmPp6JNo/gSlgxa4qlcCgCg5NUbSiwBEz2w==","_resolved":"/home/runner/work/theopen-harness/theopen-harness/dist/npm/buckeyestudio-toh-launch-environment-0.1.1-rc.2.tgz","_from":"file:/home/runner/work/theopen-harness/theopen-harness/dist/npm/buckeyestudio-toh-launch-environment-0.1.1-rc.2.tgz","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-DvvDmln9HL/JcwnDEKHIobviIQIkDjpdd3lpuwXOZv96iOkHj4ktmPp6JNo/gSlgxa4qlcCgCg5NUbSiwBEz2w==","shasum":"08b72bc3f3e72677fd7f5a3862ecfb1237df4c93","tarball":"https://registry.npmjs.org/@buckeyestudio/toh-launch-environment/-/toh-launch-environment-0.1.1-rc.2.tgz","fileCount":9,"unpackedSize":15962,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICQ9NwZ5wo9IkMKFHgs3jEPr7MrKHSplYTtM9GfjrwoJAiEA7KJocxl570BTKQIOsjjVgvfHaNi/1H/h0NURqC3NrTM="}]},"_npmUser":{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"},"directories":{},"maintainers":[{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/toh-launch-environment_0.1.1-rc.2_1787488990018_0.5619137042092841"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-23T12:43:09.860Z","0.1.1-rc.2":"2026-08-23T12:43:10.154Z","modified":"2026-08-23T12:43:10.387Z"},"maintainers":[{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"}],"description":"Immutable TheOpen Harness launch environment that records which layer supplied each value","homepage":"https://github.com/dustinwloring1988/theopen-harness#readme","repository":{"type":"git","url":"git+https://github.com/dustinwloring1988/theopen-harness.git","directory":"packages/util/launch-environment"},"author":{"name":"buckeyestudio"},"bugs":{"url":"https://github.com/dustinwloring1988/theopen-harness/issues"},"license":"MIT","readme":"# toh-launch-environment\n\n[English](README.md) | 中文\n\n把本次运行的环境冻结为一份不可变快照，并记住**每个值来自哪一层**。消费方用它而不是 `process.env` 解析面向用户的值，因为各层的可信程度并不相同，而压平后的视图无法区分它们。\n\n| 层 | 来源 id | 它是什么 |\n|---|---|---|\n| 继承的进程环境 | `process` | 启动 shell、CI 任务或容器传入的东西——本次运行的明确意图 |\n| `<invocation cwd>/.env` | `project-env` | harness 被启动于其中的项目；产品信任它配置自己的 agent（智能体） |\n| `$TOH_HOME/.env` | `user-env` | 用户自己的机器级默认值 |\n\n这些值同样会进入 `process.env`——用户自己的 `--config` 树和第三方库要读它——但那份压平的视图不是 harness 解析任何值的依据。\n\n## 解析\n\n`get(name)` 按可信度从高到低搜索所有层。`getFrom(name, sources)` 只搜索指定的层，不改变这一可信顺序。\n\n**省略某一层是拒绝，不是降级**——绝不能接受某一层的调用方直接不把它列进去，后续任何重新排序都无法让它回来。提供方适配器三层全列，因为产品信任它所运行的项目；该机制是为那些「并非如此」的决策准备的。\n\n变量名按平台自身的规则匹配：POSIX 上精确匹配，Windows 上不区分大小写。在 Windows 上做大小写敏感的查找会选错层——shell 里的 `deepseek_api_key` 与项目 `.env` 里的 `DEEPSEEK_API_KEY` 对操作系统而言是同一个变量，把它们当成两个就会让项目胜出。\n\n```ts\nimport type { Context } from '@buckeyestudio/cordis'\nimport { launchEnvironmentOf } from '@buckeyestudio/toh-launch-environment'\n\ndeclare const ctx: Context\nconst endpoint = launchEnvironmentOf(ctx).get('DEEPSEEK_BASE_URL')?.value\n```\n\n当产品 CLI（命令行界面）启动了这棵树时，`launchEnvironmentOf(ctx)` 返回启动器的快照；否则返回只含继承环境的那一层。该回退并不削弱规则：SDK 宿主或裸 `cordis.yml` 从未发现过任何文件，因此它拥有的一切确实就是它被启动时的环境。\n\n## 已知限制与暂缓事项\n\n- **快照不是子进程边界**：每一层同样会被物化进 `process.env`，因此项目里的普通变量会按 [`toh-subprocess`](../../subprocess/subprocess/README.zh.md) 的清洗规则抵达子进程。产品启动器的 [`.env` 约定](../../boot/app-boot/README.zh.md#profiles) 会在物化之前拒绝 bootstrap 变量。\n- **没有按工作区划分的层**：项目层是*调用*目录，在启动时固定。之后在 Web UI 中选择的工作区不贡献任何内容，这是刻意的：跟随它等于让模型自己的工作区在会话中途改变 harness 的环境。\n","readmeFilename":"README.zh.md","_rev":"1-631b8d700cfb3546dc6530ec1c0f1aab"}