@kitsy/cnos-docs 1.6.0 → 1.7.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.
@@ -16,3 +16,32 @@ Only promoted browser-safe values are available here.
16
16
  Framework integrations such as `@kitsy/cnos-vite`, `@kitsy/cnos-next`, and `@kitsy/cnos-webpack` are responsible for embedding that browser payload during the build.
17
17
 
18
18
  The browser runtime does not fetch config over the network. It reads from data already embedded into the bundle/runtime globals by the framework integration, so it follows the same bundle and service-worker caching behavior as the rest of your frontend assets.
19
+
20
+ ## Cross-App Browser Config
21
+
22
+ Use the same runtime for shared browser-safe values such as sibling app origins, CDN roots, public feature flags, or analytics ids.
23
+
24
+ ```yaml
25
+ public:
26
+ promote:
27
+ - value.apps.docs.origin
28
+ - value.apps.console.origin
29
+ ```
30
+
31
+ ```ts
32
+ import cnos from '@kitsy/cnos/browser';
33
+
34
+ const docsOrigin = cnos('public.apps.docs.origin');
35
+ const consoleOrigin = cnos('public.apps.console.origin');
36
+ ```
37
+
38
+ This is intentionally simple:
39
+
40
+ 1. define the values in CNOS
41
+ 2. promote them to `public.*`
42
+ 3. install the framework integration
43
+ 4. read them in browser code with `@kitsy/cnos/browser`
44
+
45
+ You should not need a second app-specific browser config mechanism on top of CNOS.
46
+
47
+ Derived public values are supported too, but only when CNOS can resolve them safely at build time. If a promoted key depends on a server-only runtime namespace such as `process.*` or `request.*`, the browser/public build fails instead of emitting unstable data.
@@ -13,3 +13,44 @@ const runtime = await createCnos({
13
13
  profile: 'stage',
14
14
  });
15
15
  ```
16
+
17
+ Common options:
18
+
19
+ - `cwd`
20
+ - `root`
21
+ - `workspace`
22
+ - `profile`
23
+ - `globalRoot`
24
+ - `cacheMode`
25
+ - `cacheTtlSeconds`
26
+ - `processEnv`
27
+
28
+ `root` can be a local path or a remote git root URI:
29
+
30
+ ```ts
31
+ const runtime = await createCnos({
32
+ root: 'git+https://github.com/org/config.git#v2.1.0',
33
+ workspace: 'travel',
34
+ });
35
+ ```
36
+
37
+ Derived values and runtime namespaces work through the explicit runtime too:
38
+
39
+ ```ts
40
+ import { createCnos } from '@kitsy/cnos/configure';
41
+
42
+ const runtime = await createCnos({
43
+ cwd: process.cwd(),
44
+ profile: 'prod',
45
+ });
46
+
47
+ runtime.registerRuntimeProvider('request', (key) => {
48
+ if (key === 'headers.host') {
49
+ return currentRequest?.headers.host;
50
+ }
51
+
52
+ return undefined;
53
+ });
54
+
55
+ const origin = runtime.value('app.origin');
56
+ ```
@@ -36,6 +36,7 @@ The runtime currently exposes:
36
36
  - `cnos.format(message)`
37
37
  - `cnos.log(message)`
38
38
  - `cnos.loadProjection(path)`
39
+ - `cnos.registerRuntimeProvider(namespace, provider)`
39
40
  - `cnos.refreshSecrets()`
40
41
  - `cnos.refreshSecret(key)`
41
42
 
@@ -67,6 +68,49 @@ await cnos.loadProjection('./.cnos-server.json');
67
68
  await cnos.ready();
68
69
  ```
69
70
 
71
+ ## Derived Values
72
+
73
+ Derived values resolve transparently through the same read APIs.
74
+
75
+ ```yaml
76
+ app:
77
+ origin:
78
+ $derive: "${value.app.protocol}://${value.app.host}:${value.app.port}"
79
+ ```
80
+
81
+ ```ts
82
+ const origin = cnos.value('app.origin');
83
+ ```
84
+
85
+ Config-only derivations are cached for the active runtime. Runtime-dependent derivations stay live:
86
+
87
+ ```yaml
88
+ server:
89
+ effective_port:
90
+ $derive:
91
+ expr: "coalesce(process.env.PORT, value.server.default_port, '3000')"
92
+ ```
93
+
94
+ ```ts
95
+ const port = cnos.value('server.effective_port');
96
+ ```
97
+
98
+ ## Runtime Providers
99
+
100
+ Declare custom runtime namespaces in the manifest, then register a provider at runtime.
101
+
102
+ ```ts
103
+ cnos.registerRuntimeProvider('request', (key) => {
104
+ if (key === 'headers.host') {
105
+ return currentRequest?.headers.host;
106
+ }
107
+
108
+ return undefined;
109
+ });
110
+ ```
111
+
112
+ That lets server-side derived values depend on live request, session, or app-framework context without adding a second config layer.
113
+
70
114
  ## Typed values
71
115
 
72
116
  CNOS values are not limited to strings. If the underlying config stores numbers, booleans, arrays, or objects, runtime reads return those values as-is.
@@ -13,6 +13,7 @@ cnos build browser --to .cnos-browser.json
13
13
  cnos build env --profile local --to .env.local
14
14
  cnos build env --profile stage --to .env.stage
15
15
  cnos build public --framework vite --to .env.production
16
+ cnos build env --profile local-domain --format docker-env --to .env.local-domain
16
17
  ```
17
18
 
18
19
  Targets:
@@ -0,0 +1,28 @@
1
+ ---
2
+ title: cnos cache
3
+ description: Inspect and manage cached remote CNOS roots.
4
+ ---
5
+
6
+ # cnos cache
7
+
8
+ Use `cache` when a package anchor points at a remote root such as a git-backed config repo.
9
+
10
+ ```bash
11
+ cnos cache list
12
+ cnos cache clear
13
+ cnos cache clear git+https://github.com/org/config.git#v2.1.0
14
+ cnos cache refresh
15
+ cnos cache refresh git+ssh://git@github.com/org/config.git#main
16
+ ```
17
+
18
+ Subcommands:
19
+
20
+ - `cache list` shows cached remote roots, resolved commits, immutability, and size
21
+ - `cache clear` removes all cached roots or one specific cached root
22
+ - `cache refresh` forces a re-fetch for the current remote root or a specific git root URI
23
+
24
+ Notes:
25
+
26
+ - immutable refs such as semantic-version tags and commit SHAs stay cached permanently
27
+ - mutable refs such as branches are refreshed based on CNOS cache policy
28
+ - remote roots are read-only when consumed through CNOS
@@ -9,3 +9,31 @@ description: Inspect resolved values, provenance, and overrides.
9
9
  cnos inspect value.app.name
10
10
  cnos inspect secret.app.token --reveal
11
11
  ```
12
+
13
+ `cnos inspect` also shows derived metadata.
14
+
15
+ ```bash
16
+ cnos inspect value.app.origin
17
+ ```
18
+
19
+ Typical output includes:
20
+
21
+ - resolved value
22
+ - expression or template source
23
+ - dependency keys
24
+ - whether the value is runtime-dependent
25
+ - which runtime namespaces it depends on
26
+
27
+ Example:
28
+
29
+ ```text
30
+ key: value.app.origin
31
+ value: https://api.kitsy.ai:443
32
+ derivedType: template
33
+ derivedExpression: ${value.app.protocol}://${value.app.host}:${value.app.port}
34
+ runtimeDependent: false
35
+ dependencies:
36
+ - value.app.host
37
+ - value.app.port
38
+ - value.app.protocol
39
+ ```
@@ -12,6 +12,22 @@ cnos value list --prefix app.
12
12
  cnos value delete app.name
13
13
  ```
14
14
 
15
+ ## Derived values
16
+
17
+ Use `--derive` for template shorthand:
18
+
19
+ ```bash
20
+ cnos value set app.origin --derive '${value.app.protocol}://${value.app.host}'
21
+ ```
22
+
23
+ Use `--derive --expr` for expression form:
24
+
25
+ ```bash
26
+ cnos value set app.effective_port --derive --expr "coalesce(process.env.PORT, value.app.default_port, '3000')"
27
+ ```
28
+
29
+ CNOS stores these as first-class derived values, not as opaque strings.
30
+
15
31
  ## Typed input
16
32
 
17
33
  `cnos value set` parses the input as YAML before writing it. That means you can store more than strings.
@@ -46,3 +62,4 @@ cnos read value.app.name
46
62
  - Values are private by default.
47
63
  - To expose a value to browser/public surfaces, use `cnos promote`.
48
64
  - To expose a value as shell env, map it through `envMapping.explicit` or `cnos promote --to env`.
65
+ - Derived values can be authored only under writable data namespaces such as `value.*` and custom writable data namespaces.
@@ -30,6 +30,31 @@ const port = cnos.value('server.port');
30
30
  const token = cnos.secret('app.token');
31
31
  ```
32
32
 
33
+ Derived server config stays inside CNOS too:
34
+
35
+ ```yaml
36
+ server:
37
+ effective_port:
38
+ $derive:
39
+ expr: "coalesce(process.env.PORT, value.server.default_port, '3000')"
40
+ ```
41
+
42
+ ```ts
43
+ const port = cnos.value('server.effective_port');
44
+ ```
45
+
46
+ If you need live request or session context, declare a runtime namespace and register a provider:
47
+
48
+ ```ts
49
+ cnos.registerRuntimeProvider('request', (key) => {
50
+ if (key === 'headers.host') {
51
+ return currentRequest?.headers.host;
52
+ }
53
+
54
+ return undefined;
55
+ });
56
+ ```
57
+
33
58
  Env export bridge:
34
59
 
35
60
  ```bash
@@ -8,9 +8,10 @@ description: Use CNOS in build and deploy pipelines without committing generated
8
8
  Common patterns:
9
9
 
10
10
  ```bash
11
- cnos export env --profile stage --to .env.stage
12
- cnos export env --public --framework vite --profile stage --to .env.stage
11
+ cnos build env --profile stage --to .env.stage
12
+ cnos build public --framework vite --profile stage --to .env.stage
13
13
  cnos run --profile stage -- pnpm build
14
+ cnos build server --profile prod --to dist/.cnos-server.json
14
15
  ```
15
16
 
16
17
  For CI-backed vaults:
@@ -19,3 +20,18 @@ For CI-backed vaults:
19
20
  cnos vault create github-ci --provider github-secrets --no-passphrase
20
21
  cnos secret set app.token APP_TOKEN --vault github-ci
21
22
  ```
23
+
24
+ GitHub Actions example:
25
+
26
+ ```yaml
27
+ - name: Install deps
28
+ run: pnpm install --frozen-lockfile
29
+
30
+ - name: Build CNOS env
31
+ run: cnos build env --profile stage --to .env.stage
32
+
33
+ - name: Build app
34
+ run: pnpm build
35
+ ```
36
+
37
+ Use `cnos run` when you do not need an intermediate env file. Use `cnos build env` or `cnos build public` when the build tool or deploy step expects a file artifact.
@@ -0,0 +1,136 @@
1
+ ---
2
+ title: Containers, Kubernetes, and GitHub Actions
3
+ description: Use CNOS-generated artifacts in Docker, Docker Compose, Kubernetes, and GitHub Actions without making .env files the source of truth.
4
+ ---
5
+
6
+ # Containers, Kubernetes, and GitHub Actions
7
+
8
+ CNOS should stay the source of truth. Containers and pipelines should consume derived artifacts.
9
+
10
+ Use these patterns:
11
+
12
+ - `cnos build env` when the runtime expects flat env vars
13
+ - `cnos build server` when a server runtime should consume a CNOS projection artifact
14
+ - `cnos run` when a child process should get CNOS directly at launch time
15
+
16
+ ## Docker
17
+
18
+ Generate a Docker-friendly env file:
19
+
20
+ ```bash
21
+ cnos build env --profile local-domain --format docker-env --to .docker/runtime/current.env
22
+ ```
23
+
24
+ That file is a derived artifact. Keep it gitignored.
25
+
26
+ For a production-style local preview flow:
27
+
28
+ ```bash
29
+ pnpm build:local-domain:all
30
+ cnos build env --profile local-domain --format docker-env --to .docker/runtime/current.env
31
+ docker compose up --build
32
+ ```
33
+
34
+ Use this when:
35
+ - your image or emulator runtime expects env vars
36
+ - you want one fixed runtime env file per profile
37
+ - the build already consumed the same CNOS profile
38
+
39
+ ## Docker Compose
40
+
41
+ Recommended compose pattern:
42
+
43
+ ```yaml
44
+ services:
45
+ app:
46
+ env_file:
47
+ - ./.docker/runtime/current.env
48
+ ```
49
+
50
+ This keeps runtime env injection explicit and lets the same CNOS profile drive:
51
+ - the build step
52
+ - the container runtime
53
+ - local emulators
54
+
55
+ For browser builds behind nginx or another proxy:
56
+ - build the app first with `cnos run --profile <name> -- pnpm build`
57
+ - then feed compose/runtime with `cnos build env --format docker-env`
58
+
59
+ ## Kubernetes
60
+
61
+ Use CNOS to render the env payload before applying manifests:
62
+
63
+ ```bash
64
+ cnos build env --profile stage --format yaml --to k8s/generated/app-config.yaml
65
+ ```
66
+
67
+ Or generate a flat env file and convert it into a ConfigMap or Secret with your existing tooling:
68
+
69
+ ```bash
70
+ cnos build env --profile stage --format dotenv --to .artifacts/stage.env
71
+ kubectl create configmap app-config --from-env-file=.artifacts/stage.env --dry-run=client -o yaml
72
+ ```
73
+
74
+ Rules:
75
+ - do not make Kubernetes manifests the source of truth for application config
76
+ - do not embed decrypted CNOS secret values into build artifacts by default
77
+ - prefer runtime secret providers or platform-native secrets for secret plaintext
78
+
79
+ ## GitHub Actions
80
+
81
+ Two good patterns exist.
82
+
83
+ ### 1. Build with direct CNOS injection
84
+
85
+ ```yaml
86
+ - name: Install deps
87
+ run: pnpm install --frozen-lockfile
88
+
89
+ - name: Build with CNOS
90
+ run: cnos run --profile stage -- pnpm build
91
+ ```
92
+
93
+ ### 2. Materialize an env artifact first
94
+
95
+ ```yaml
96
+ - name: Build CNOS env file
97
+ run: cnos build env --profile stage --to .env.stage
98
+
99
+ - name: Build app
100
+ run: pnpm build
101
+ ```
102
+
103
+ For browser-only frameworks:
104
+
105
+ ```yaml
106
+ - name: Build public env for Vite
107
+ run: cnos build public --framework vite --profile stage --to .env.stage
108
+ ```
109
+
110
+ For Next:
111
+
112
+ ```yaml
113
+ - name: Build public env for Next
114
+ run: cnos build public --framework next --profile prod --to .env.production
115
+ ```
116
+
117
+ For server packaging:
118
+
119
+ ```yaml
120
+ - name: Build server projection
121
+ run: cnos build server --profile prod --to dist/.cnos-server.json
122
+ ```
123
+
124
+ ## Secret handling
125
+
126
+ Keep this split clear:
127
+
128
+ - non-secret config can become a build or runtime artifact
129
+ - decrypted secret plaintext should not become a build artifact by default
130
+
131
+ Use:
132
+ - CNOS vault refs
133
+ - platform env injection
134
+ - runtime secret hydration
135
+
136
+ Do not rely on generated env files for secret rotation-sensitive server secrets unless you deliberately accept that tradeoff.
@@ -0,0 +1,130 @@
1
+ ---
2
+ title: Derived Values
3
+ description: Compute config from other CNOS keys and live runtime namespaces.
4
+ ---
5
+
6
+ # Derived Values
7
+
8
+ Derived values let you keep config composition inside CNOS instead of re-implementing it in app code.
9
+
10
+ Template shorthand:
11
+
12
+ ```yaml
13
+ app:
14
+ origin:
15
+ $derive: "${value.app.protocol}://${value.app.host}:${value.app.port}"
16
+ ```
17
+
18
+ Expression form:
19
+
20
+ ```yaml
21
+ app:
22
+ effective_port:
23
+ $derive:
24
+ expr: "coalesce(process.env.PORT, value.app.default_port, '3000')"
25
+ ```
26
+
27
+ ## Write from the CLI
28
+
29
+ ```bash
30
+ cnos value set app.origin --derive '${value.app.protocol}://${value.app.host}'
31
+ cnos value set app.effective_port --derive --expr "coalesce(process.env.PORT, value.app.default_port, '3000')"
32
+ ```
33
+
34
+ ## Built-ins
35
+
36
+ Supported functions:
37
+
38
+ - `concat(...)`
39
+ - `coalesce(...)`
40
+ - `when(condition, thenValue, elseValue)`
41
+ - `exists(ref)`
42
+ - `eq(a, b)`
43
+ - `ne(a, b)`
44
+
45
+ The language is intentionally small and safe. There is no arbitrary JavaScript execution.
46
+
47
+ ## Runtime Namespaces
48
+
49
+ `process.*` is the built-in runtime namespace. It stays live between reads.
50
+
51
+ ```yaml
52
+ app:
53
+ effective_port:
54
+ $derive:
55
+ expr: "coalesce(process.env.PORT, value.app.default_port, '3000')"
56
+ ```
57
+
58
+ Custom runtime namespaces are declared in the manifest and populated by the host app:
59
+
60
+ ```yaml
61
+ namespaces:
62
+ runtime:
63
+ request:
64
+ description: HTTP request context
65
+ server_only: true
66
+ ```
67
+
68
+ ```ts
69
+ import cnos from '@kitsy/cnos';
70
+
71
+ await cnos.ready();
72
+
73
+ cnos.registerRuntimeProvider('request', (key) => {
74
+ if (key === 'headers.host') {
75
+ return currentRequest?.headers.host;
76
+ }
77
+
78
+ return undefined;
79
+ });
80
+ ```
81
+
82
+ ## Caching Rules
83
+
84
+ - config-only derivations are cached once per resolution pass
85
+ - runtime-dependent derivations are never cached
86
+
87
+ That means `value.app.origin` is stable until the next `createCnos()` or `cnos.ready()`, while `value.app.effective_port` can change between reads when `process.env.PORT` changes.
88
+
89
+ ## Browser and Server Behavior
90
+
91
+ Browser/public outputs always need concrete values.
92
+
93
+ - config-only derived values can be promoted and embedded normally
94
+ - runtime-dependent derived values that rely on server-only namespaces are rejected for browser/public builds
95
+
96
+ Server projections split the result:
97
+
98
+ - `values` contains concrete non-secret values, including config-only derivations
99
+ - `derived` contains live runtime-dependent formulas
100
+ - `runtimeNamespaces` lists which runtime providers the server runtime needs
101
+
102
+ ## Use Cases
103
+
104
+ Cross-app browser links:
105
+
106
+ ```yaml
107
+ apps:
108
+ cnos:
109
+ origin:
110
+ $derive: "${value.platform.protocol}://${value.apps.cnos.host}"
111
+
112
+ public:
113
+ promote:
114
+ - value.apps.cnos.origin
115
+ ```
116
+
117
+ ```ts
118
+ import cnos from '@kitsy/cnos/browser';
119
+
120
+ const cnosOrigin = cnos('public.apps.cnos.origin');
121
+ ```
122
+
123
+ Server fallback port:
124
+
125
+ ```yaml
126
+ server:
127
+ port:
128
+ $derive:
129
+ expr: "coalesce(process.env.PORT, value.server.default_port, '3000')"
130
+ ```
@@ -40,6 +40,58 @@ console.log(cnos('public.app.apiBaseUrl'));
40
40
  console.log(import.meta.env.VITE_APP_API_BASE_URL);
41
41
  ```
42
42
 
43
+ Cross-app browser links work the same way. Put the browser-safe origins in CNOS, promote them, and let the Vite plugin handle the embedding:
44
+
45
+ ```yaml
46
+ public:
47
+ promote:
48
+ - value.apps.main.origin
49
+ - value.apps.cnos.origin
50
+ - value.apps.coop.origin
51
+ ```
52
+
53
+ ```yaml
54
+ apps:
55
+ main:
56
+ origin: https://kitsy.ai
57
+ cnos:
58
+ origin: https://cnos.kitsy.ai
59
+ coop:
60
+ origin: https://coop.kitsy.ai
61
+ ```
62
+
63
+ Then in UI code:
64
+
65
+ ```ts
66
+ import cnos from '@kitsy/cnos/browser';
67
+
68
+ const cnosOrigin = cnos('public.apps.cnos.origin');
69
+ const coopOrigin = cnos('public.apps.coop.origin');
70
+ ```
71
+
72
+ That is the point of the integration. You promote once, keep using the same logical reads in UI code, and `@kitsy/cnos-vite` makes sure the values are already present in the browser bundle.
73
+
74
+ Derived public values work the same way as long as they are build-safe:
75
+
76
+ ```yaml
77
+ apps:
78
+ cnos:
79
+ origin:
80
+ $derive: "${value.platform.protocol}://${value.apps.cnos.host}"
81
+
82
+ public:
83
+ promote:
84
+ - value.apps.cnos.origin
85
+ ```
86
+
87
+ ```ts
88
+ import cnos from '@kitsy/cnos/browser';
89
+
90
+ const cnosOrigin = cnos('public.apps.cnos.origin');
91
+ ```
92
+
93
+ If a promoted derived value depends on a server-only runtime namespace such as `process.*` or a custom `request.*`, CNOS rejects the browser/public build instead of leaking an unstable value.
94
+
43
95
  Migration path:
44
96
 
45
97
  1. keep `VITE_*` working through generated env files
@@ -15,6 +15,7 @@ Use generated env files as a **bridge**, not as the source of truth.
15
15
  cnos build env --profile local --to .env.local
16
16
  cnos build env --profile stage --to .env.stage
17
17
  cnos build env --profile prod --to .env.prod
18
+ cnos build env --profile local-domain --format docker-env --to .docker/runtime/current.env
18
19
  ```
19
20
 
20
21
  ## Watched dev loop
@@ -36,3 +37,4 @@ cnos build env --public --framework next --profile prod --to .env.production
36
37
  - keep generated `.env.*` files gitignored
37
38
  - migrate app code toward direct CNOS reads over time
38
39
  - keep secrets on runtime/vault flows instead of materializing them into env files by default
40
+ - use `docker-env` when Docker or Docker Compose expects a runtime env file
@@ -0,0 +1,86 @@
1
+ ---
2
+ title: Remote Roots
3
+ description: Point .cnosrc.yml at a remote git-backed CNOS root and consume it through the local cache.
4
+ ---
5
+
6
+ # Remote Roots
7
+
8
+ `.cnosrc.yml` can point at either a local `.cnos` directory or a remote git-backed root.
9
+
10
+ Local:
11
+
12
+ ```yaml
13
+ root: ./.cnos
14
+ ```
15
+
16
+ Remote:
17
+
18
+ ```yaml
19
+ root: git+https://github.com/org/config.git#v2.1.0
20
+ workspace: travel
21
+ ```
22
+
23
+ Remote roots are resolved into the CNOS cache, then loaded exactly like a local manifest root.
24
+
25
+ ## Supported URIs
26
+
27
+ Recommended production form:
28
+
29
+ ```yaml
30
+ root: git+https://github.com/org/config.git#v2.1.0
31
+ ```
32
+
33
+ Private repo over SSH:
34
+
35
+ ```yaml
36
+ root: git+ssh://git@github.com/org/private-config.git#main
37
+ ```
38
+
39
+ Subpath inside the repo:
40
+
41
+ ```yaml
42
+ root: git+https://github.com/org/monorepo.git#v2.1.0:config/.cnos
43
+ ```
44
+
45
+ ## Cache Behavior
46
+
47
+ - semantic-version tags and commit SHAs are treated as immutable
48
+ - branch refs are treated as mutable
49
+ - runtime reads use a cache TTL
50
+ - `cnos build` refreshes mutable refs before building artifacts
51
+ - `cnos cache refresh` forces a re-fetch when needed
52
+
53
+ Inspect the cache:
54
+
55
+ ```bash
56
+ cnos cache list
57
+ ```
58
+
59
+ Override TTL for one command when needed:
60
+
61
+ ```bash
62
+ cnos read value.app.name --cache-ttl 0
63
+ cnos watch --cache-ttl 15 -- node server.js
64
+ ```
65
+
66
+ ## Read-Only Model
67
+
68
+ Remote roots are consumed as read-only config.
69
+
70
+ These work:
71
+
72
+ ```bash
73
+ cnos read value.app.name
74
+ cnos build env --to .env.stage
75
+ cnos run -- node server.js
76
+ ```
77
+
78
+ These are blocked:
79
+
80
+ ```bash
81
+ cnos value set app.name demo
82
+ cnos promote value.app.name --to public
83
+ cnos vault create default
84
+ ```
85
+
86
+ The right workflow is to edit the source config repo and then let consumers refresh the cached root.
@@ -22,6 +22,13 @@ root: ../../.cnos
22
22
  workspace: travel
23
23
  ```
24
24
 
25
+ Child app from a remote config repo:
26
+
27
+ ```yaml
28
+ root: git+https://github.com/org/config.git#v2.1.0
29
+ workspace: travel
30
+ ```
31
+
25
32
  `.cnosrc.yml` is the only discovery anchor. CNOS does not walk upward looking for `.cnos` directories. It looks for `.cnosrc.yml` within a bounded package-root search window, then resolves the real `.cnos` root from there.
26
33
 
27
34
  Typical manifest shape:
@@ -12,6 +12,7 @@ Primary namespaces:
12
12
  - `meta.*`
13
13
  - `process.*` for server-only ambient runtime state
14
14
  - custom data namespaces such as `flags.*` or `config.*` when declared in `.cnos/cnos.yml`
15
+ - custom runtime namespaces declared under `namespaces.runtime`
15
16
 
16
17
  Derived surfaces:
17
18
 
@@ -35,3 +36,36 @@ Custom data namespaces can be:
35
36
  - `process.env.PATH`
36
37
 
37
38
  `process.*` cannot be promoted or exported.
39
+
40
+ ## Runtime Namespaces
41
+
42
+ Runtime namespaces are not populated from config files. They are declared in the manifest and populated by the host runtime.
43
+
44
+ ```yaml
45
+ namespaces:
46
+ runtime:
47
+ request:
48
+ description: HTTP request context
49
+ server_only: true
50
+ ```
51
+
52
+ Use them from derived values:
53
+
54
+ ```yaml
55
+ app:
56
+ current_host:
57
+ $derive:
58
+ expr: "coalesce(request.headers.host, value.app.default_host)"
59
+ ```
60
+
61
+ And register providers in server code:
62
+
63
+ ```ts
64
+ cnos.registerRuntimeProvider('request', (key) => {
65
+ if (key === 'headers.host') {
66
+ return currentRequest?.headers.host;
67
+ }
68
+
69
+ return undefined;
70
+ });
71
+ ```
package/manifest.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  product: cnos
2
2
  title: CNOS Documentation
3
3
  tagline: Configuration orchestration for apps, monorepos, and deployment pipelines
4
- version: "1.5"
4
+ version: "1.7"
5
5
 
6
6
  sidebar:
7
7
  - group: Getting Started
@@ -29,10 +29,16 @@ sidebar:
29
29
  label: SSR Projects
30
30
  - path: guides/ci-cd
31
31
  label: CI/CD Pipelines
32
+ - path: guides/containers-and-actions
33
+ label: Containers and Actions
32
34
  - path: guides/workspaces
33
35
  label: Workspaces and Monorepos
36
+ - path: guides/remote-roots
37
+ label: Remote Roots
34
38
  - path: guides/profiles
35
39
  label: Profiles and Environments
40
+ - path: guides/derived-values
41
+ label: Derived Values
36
42
  - path: guides/secrets
37
43
  label: Secrets and Vaults
38
44
  - path: guides/migration
@@ -61,6 +67,8 @@ sidebar:
61
67
  label: cnos export
62
68
  - path: cli/build
63
69
  label: cnos build env
70
+ - path: cli/cache
71
+ label: cnos cache
64
72
  - path: cli/dev
65
73
  label: cnos dev env
66
74
  - path: cli/run
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitsy/cnos-docs",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "Source-of-truth CNOS documentation content for Astro Starlight and other static docs consumers.",
5
5
  "type": "module",
6
6
  "exports": {