@configdirector/cli 0.1.0-beta.2 → 0.5.0-beta.1
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/CHANGELOG.md +40 -0
- package/README.md +153 -10
- package/dist/configdirector.mjs +1403 -69
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,46 @@ All notable changes to `@configdirector/cli` are documented here. The format fol
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.5.0-beta.1] - 2026-10-17
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `configdirector targeting-rules set <key> --environment <slug> --rules <file>` replaces a config's targeting rules in one environment with the rules in a JSON file, or in stdin with `--rules -`. The file holds `defaultValue`, the default targeting rule value, and `rules`, exactly as the Admin API takes them, so you can take an environment's entry of `targets` from `configs get --json`, edit it and write it back. Every rule of the environment is replaced. A rule, condition or percentage without an `id` gets a new one, and the IDs given are kept. The CLI checks only that the file holds a JSON object: ConfigDirector checks the rules, and when it refuses them `set` exits with 2 and lists its reasons.
|
|
12
|
+
- `targeting-rules set` asks for no confirmation and treats a live environment like any other. It prints the key, the environment, the number of rules and the default targeting rule value it wrote. `--json` prints the request it sent, with the IDs it gave, since the Admin API answers with no body. It exits with 2 when no config in the project has the key, or when no environment has the slug, listing the project's environment slugs. It needs `projects:read`, `environments:read` and `config-targeting-rules:update`. The change shows in the audit log with the source CLI.
|
|
13
|
+
- `configdirector targeting-rules reference` prints the format targeting rules take: notes on how rules are evaluated, then the condition kinds, the attributes a condition can test, the context kind operators, the segment operators and the operators for each target type. `--json` prints the whole document as received, including the JSON Schema of the request `targeting-rules set` sends. It needs an API token, with any permissions, and no project. The notes are the ones the MCP server's `get_targeting_rules_reference` tool gives, so they name the MCP tools: `update_targeting_rules` is what `targeting-rules set` does, and `get_config` what `configs get` does.
|
|
14
|
+
|
|
15
|
+
## [0.4.0-beta.1] - 2026-10-17
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- `configdirector configs create` creates a config from options that match the Admin API's fields one to one, with no guessing and no prompts. `--key`, `--type`, `--role`, `--lifetime` and `--default-value` are required; `--default-value` is the default targeting rule value every environment starts with, not the in-code default value. `--description`, `--client-only` or `--server-only` (client and server SDKs without either), `--tag <name>`, repeatable, naming an existing tag, and `--variation <name=value>`, repeatable, for an experiment, are optional.
|
|
20
|
+
- The values of `--default-value` and `--variation` are read in the config's type: `true` or `false`, a number, text, or JSON for a JSON config, with `@file` reading the JSON from a file. A value that does not fit the type is a usage error, and nothing is sent.
|
|
21
|
+
- Constraint options, each accepted only by its types: `--min` and `--max`, which a value may equal, for an integer, float or timespan; `--exclusive-min` and `--exclusive-max` for an integer or float; `--unit` and `--allow-fractions` for a timespan, which needs `--unit`, `--min` and `--max`; `--allowed-value`, repeatable, and `--enum-value-type string|number` (default `string`) for an enum; `--https-only` for a URL, without which any HTTP or HTTPS URL is accepted; and `--json-schema <file>` for a JSON config. An option of another type is a usage error naming the types it belongs to. A timespan without `--unit`, `--min` or `--max` is a usage error too. `configs create --help` lists them grouped by type.
|
|
22
|
+
- `configs create` prints the created config's key, type, role, lifetime and availability, and the default targeting rule value every environment starts with; `--json` prints the created config as received. When the project already has a config with the key, nothing is created: it prints that config's key, type, role, lifetime and lifecycle state and exits with 1, and `--json` prints that config as received. Any other refusal exits with 2 and lists the Admin API's reasons. It needs `projects:read`, `configs:create` and `configs:read`, and `tags:read` and `config-settings:update` for `--tag`. The config shows in the audit log with the source CLI.
|
|
23
|
+
|
|
24
|
+
## [0.3.0-beta.1] - 2026-10-17
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- `configdirector projects list` lists your organization's projects with their slugs and names, whichever project `--project`, `CONFIGDIRECTOR_PROJECT` or `configdirector.json` selects.
|
|
29
|
+
- `configdirector environments list` lists the project's environments with their slugs and names, marking the live ones.
|
|
30
|
+
- `configdirector configs list` lists the project's configs with their type, role, lifetime and lifecycle state. `--tag <name>`, repeatable, lists the configs that have any of the tags, and a name no tag has exits with 2; it needs the `tags:read` permission. `--untagged` lists the configs without tags and cannot be combined with `--tag`. `--state <state>` lists the configs in one lifecycle state: `new`, `in-use`, `settled`, `archive-ready` or `stale`.
|
|
31
|
+
- `configdirector configs get <key>` shows a config's settings, including its type's constraints, then its targeting rules in every environment, written as `evaluate` writes them, with the default targeting rule value last. A segment condition names the segment, or shows its ID when the token lacks `segments:read`. An old key works, and the output says which key is current.
|
|
32
|
+
- `configdirector configs activity <key>` shows when SDKs last evaluated a config, one line per environment, SDK key kind, SDK name and SDK version, with the time in UTC.
|
|
33
|
+
- `configdirector segments list` lists the project's segments with how many configs use each, and `configdirector segments get <key>` shows a segment's condition groups and its environment overrides, naming each override's environment by its slug, or by its ID when the token lacks `environments:read`.
|
|
34
|
+
- With `--json`, each new command prints the Admin API's response as received, except `configs list --state`, which prints only the configs in that state. A key no config or segment has exits with 2. Every new command but `projects list` takes the project from `--project`, `CONFIGDIRECTOR_PROJECT` or `configdirector.json`, as `scan` does.
|
|
35
|
+
- `scan` finds the calls of a Kotlin, Java or C# file that reaches the client through a class of your own whose file imports the SDK, such as `Flags.client.getBoolean("new-checkout", false)` with an `object Flags` holding the client, in a file that never names the SDK. The class must be in a file named after it, such as `Flags.kt`, `Flags.java` or `Flags.cs`. Kotlin and Java find it through an import, a static import, a wildcard import, or in the file's own directory for a class of the same package; C# finds it anywhere in the project of the nearest `.csproj`, so a global using of the SDK's namespace works. Only that one class is read, not the classes it uses in turn, and a Kotlin client declared at the top level of a file is not followed. A call that only looks like an SDK call, such as Android's `SharedPreferences.getBoolean` or ASP.NET's `IConfiguration.GetValue`, is still not reported in a file that uses no such class.
|
|
36
|
+
|
|
37
|
+
## [0.2.0-beta.1] - 2026-10-17
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
|
|
41
|
+
- `configdirector evaluate <key> --environment <slug>` shows the value a context gets for a config in an environment, and why. It uses the evaluator the SDKs use, so the value is the one your application gets.
|
|
42
|
+
- `evaluate` prints the value and the rule that served it, or the default targeting rule. Then it lists each rule in order with what it tests and its outcome. A rule that did not match names the first condition that failed and the context's value for it, or the bucket a percentage rollout put the context in. A rule after the one that served the value is not evaluated, and a rule that could not be evaluated is shown as errored.
|
|
43
|
+
- An old key of a renamed config evaluates the config, and the output says which key is current. `--json` prints the Admin API's response as received. Nothing is recorded: an evaluation from the CLI is not SDK activity.
|
|
44
|
+
- `evaluate` takes the context one of three ways. `--context-kind` (default `user`), `--context-id`, `--context-name` and the repeatable `--context-trait name=value` give it option by option, and `name:=<json>` gives a trait a number, boolean, array or object value, as in `--context-trait beta:=true`. `--context-json '{...}'` or `--context-json @file` gives the whole context as a JSON object. `--saved-context <kind>:<identifier>` names a context ConfigDirector saved from SDK evaluations in that environment. Combining two of these ways is a usage error. With none, the config is evaluated for an empty context, as an SDK given none would.
|
|
45
|
+
- `evaluate` needs the `environments:read` permission as well as `projects:read` and `configs:read`, and `contexts:read` for `--saved-context`. It exits with 2 when no config in the project has the key, when no environment has the slug, listing the project's environment slugs, or when no saved context in the environment has the context kind and identifier. The project comes from `--project`, `CONFIGDIRECTOR_PROJECT` or `configdirector.json`, as for `scan`.
|
|
46
|
+
|
|
7
47
|
## [0.1.0-beta.2] - 2026-10-16
|
|
8
48
|
|
|
9
49
|
### Changed
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ConfigDirector CLI
|
|
2
2
|
|
|
3
|
-
`configdirector` is the command line tool for [ConfigDirector](https://www.configdirector.com), the managed configuration and feature flag service. It is in beta: commands and output may change before 1.0. This release signs in, links a repository to a project, lists where the repository's code reads config keys,
|
|
3
|
+
`configdirector` is the command line tool for [ConfigDirector](https://www.configdirector.com), the managed configuration and feature flag service. It is in beta: commands and output may change before 1.0. This release signs in, links a repository to a project, lists where the repository's code reads config keys, checks those keys against the project's configs, shows the value a context gets for a config and why, reads a project's environments, configs, targeting rules and segments, creates configs, and replaces a config's targeting rules in an environment.
|
|
4
4
|
|
|
5
5
|
The [CLI page of the ConfigDirector docs](https://docs.configdirector.com/integrations/cli) covers the API token, CI setup for GitHub Actions and GitLab, and what each problem `validate` reports means for your build.
|
|
6
6
|
|
|
@@ -46,9 +46,9 @@ A call that passes a constant instead of a string is reported under the constant
|
|
|
46
46
|
|
|
47
47
|
The scan also looks for the project's current and deprecated keys wherever they appear as a quoted string outside those calls, such as in a wrapper function, a key list or a test fixture, and reports each as an indirect reference under its key. An indirect reference in a test directory or a test-named file, such as `test/`, `checkout.test.ts`, `checkout_test.go`, `test_checkout.py` or `CheckoutTests.cs`, is marked as a test, whereas a direct reference is marked as a test only when the call is a test client call. The definition of a constant that an SDK call reads is not repeated as an indirect reference.
|
|
48
48
|
|
|
49
|
-
A call is found when its file imports the SDK, or imports a file of the repository that does, such as the setup module the SDK docs create. In Swift and Go, it is also found when another file of the same Swift target or Go package imports the SDK, since those files use each other's declarations without an import. A `getValue` from another library is not reported unless its file,
|
|
49
|
+
A call is found when its file imports the SDK, or imports a file of the repository that does, such as the setup module the SDK docs create. In Swift and Go, it is also found when another file of the same Swift target or Go package imports the SDK, since those files use each other's declarations without an import. In Kotlin, Java and C#, it is also found when the file uses a class of your own whose file imports the SDK, such as an `object Flags` or a static class that holds the client. A `getValue` from another library is not reported unless its file, its Swift target or Go package, or a class of your own that it uses imports one of those, so Android's `SharedPreferences.getBoolean` and ASP.NET's `IConfiguration.GetValue` are not reported next to a class that holds the client. Imports are followed one level deep: relative imports and path aliases in JavaScript and TypeScript, Python modules, Dart files including your own `package:` imports, and Go packages of the same module. When the imported file does not import the SDK itself, the scan follows what it re-exports, up to two steps, so an `index` file or a barrel library in front of the setup module works: `export { client } from "./setup"` and `export * from "./setup"` in JavaScript and TypeScript, `export 'src/setup.dart';` in Dart, and relative imports such as `from .flags import client` in a Python package's `__init__.py`. A file that reaches the client through a second ordinary import, a re-export written as an import followed by a separate `export`, or a CommonJS `module.exports` is not scanned. A Go package is the `.go` files of one directory with the same `package` name, so an external test package such as `package shop_test` counts only through its own imports. A Swift target is found from the nearest `Package.swift` or Xcode project above the file: in a Swift package, each directory under `Sources/` or `Tests/` is a target; an Xcode project's directory is one target; with neither, the file's own directory is. A class of your own counts when its file is named after it, such as `Flags.kt`, `Flags.java` or `Flags.cs`, and only that class is read, not the classes it uses in turn. Kotlin and Java find it through the file's imports, including `import static` and wildcard imports, under the source directory its `package` points to, and among the files of its own directory, so a class of the same package in another source directory or module, such as a test in `src/test/java` using a class of `src/main/java`, is not followed. When the directory does not match the `package`, as when the directories leave out the common root package, the imports are not followed. C# finds it as a `.cs` file of that name anywhere in the project of the nearest `.csproj`, outside `bin`, `obj` and the directories the scan always skips, whatever brings the SDK's namespace in, a global using included. A Kotlin client declared at the top level of a file, outside any object or class, is not followed. Nuxt's auto-imported composables need no import. A Kotlin or Java file belongs to the Android SDK when the nearest Gradle build file above it is an Android module, and to the Java server SDK otherwise. A Nuxt file belongs to the Nuxt server SDK when it is in the `server` directory next to the nearest `nuxt.config`, and to the Nuxt client SDK otherwise; a Next.js file belongs to the client or the server SDK by the entry point it imports.
|
|
50
50
|
|
|
51
|
-
A path alias such as `@/lib/config-director` is resolved the way TypeScript resolves it, from `compilerOptions.paths` and `baseUrl` in the nearest `tsconfig.json` above the importing file, or `jsconfig.json` when that directory has no `tsconfig.json`. Configs it extends with a relative path count, and when it declares no aliases of its own, the configs listed in its `references` are tried in order, as in Vite's templates. Nuxt's `~` and `@` aliases work once `nuxt prepare`, a dev run or a build has generated the `.nuxt` configs. Aliases set only in bundler configuration, such as `resolve.alias` in `vite.config.ts` or webpack, are not followed. These configs and the files they point to, like the other files of a Swift target or Go package, are read even when the scan would skip them, as long as they are under 1 MB.
|
|
51
|
+
A path alias such as `@/lib/config-director` is resolved the way TypeScript resolves it, from `compilerOptions.paths` and `baseUrl` in the nearest `tsconfig.json` above the importing file, or `jsconfig.json` when that directory has no `tsconfig.json`. Configs it extends with a relative path count, and when it declares no aliases of its own, the configs listed in its `references` are tried in order, as in Vite's templates. Nuxt's `~` and `@` aliases work once `nuxt prepare`, a dev run or a build has generated the `.nuxt` configs. Aliases set only in bundler configuration, such as `resolve.alias` in `vite.config.ts` or webpack, are not followed. These configs and the files they point to, like the other files of a Swift target or Go package and the Kotlin, Java and C# classes a file uses, are read even when the scan would skip them, as long as they are under 1 MB; only C# classes in `bin`, `obj` and the directories the scan always skips are not looked for.
|
|
52
52
|
|
|
53
53
|
The scan skips what `.gitignore` ignores, the `node_modules`, `vendor`, `build`, `dist` and `target` directories, binary files and files over 1 MB. In `configdirector.json`, `include` limits the scan to the files matching its globs, and `exclude` skips the files matching its globs.
|
|
54
54
|
|
|
@@ -74,16 +74,159 @@ A test client call, such as `setValue` or `createTestClient`, is checked for unk
|
|
|
74
74
|
|
|
75
75
|
The output lists the problems grouped by kind, with the file, the line, the key and what is wrong, such as the type a timespan is served as, then counts the references checked. With `--json`, `validate` prints the scan's JSON with a `findings` array; `schema/scan-output.schema.json` describes it.
|
|
76
76
|
|
|
77
|
+
## See what a context gets for a config
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
configdirector evaluate new-checkout --environment production --context-id 123 --context-trait plan=pro
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`evaluate` evaluates the environment's saved targeting rules for a context with the evaluator the SDKs use, so the value it shows is the one your application gets. It also shows the rule that served the value, and what each rule tests and what happened to it:
|
|
84
|
+
|
|
85
|
+
```txt
|
|
86
|
+
new-checkout in Production for user 123
|
|
87
|
+
|
|
88
|
+
true, served by rule 2
|
|
89
|
+
|
|
90
|
+
1. 50% get true not matched: bucket 71.3 is outside 0 to 50
|
|
91
|
+
2. plan is one of pro, team: true matched
|
|
92
|
+
3. in segment Beta testers: true not evaluated
|
|
93
|
+
Default targeting rule: false
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
A rule that did not match names the first condition that failed and the context's value for it, as in `plan is one of pro, team, but it is "free"`, or the bucket a percentage rollout put the context in. A rule after the one that served the value is not evaluated, and a rule that could not be evaluated is shown as errored.
|
|
97
|
+
|
|
98
|
+
`--environment` takes the environment's slug and is required. Give the context one of three ways:
|
|
99
|
+
|
|
100
|
+
- `--context-kind` (default `user`), `--context-id`, `--context-name`, and `--context-trait name=value` for each trait. A trait's value is a string; write `name:=` followed by JSON for a number, boolean, array or object, as in `--context-trait beta:=true` or `--context-trait age:=30`. For nested traits, use `--context-json`.
|
|
101
|
+
- `--context-json '{"identifier": "123", "traits": {"plan": "pro"}}'`, or `--context-json @context.json` to read it from a file. The object takes `kind`, `identifier`, `name` and `traits`.
|
|
102
|
+
- `--saved-context user:123`, the context kind and identifier of a context ConfigDirector saved from SDK evaluations in that environment. It is evaluated with its stored name and traits.
|
|
103
|
+
|
|
104
|
+
Without any of them, the config is evaluated for an empty context, as an SDK given none would. A renamed config can be evaluated by an old key; the output then starts with a line naming the current key. With `--json`, `evaluate` prints the Admin API's response as received.
|
|
105
|
+
|
|
106
|
+
`evaluate` needs a token with `environments:read` as well as `projects:read` and `configs:read`, and `contexts:read` for `--saved-context`. Nothing is recorded: an evaluation from the CLI is not SDK activity.
|
|
107
|
+
|
|
108
|
+
## Browse the project
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
configdirector projects list
|
|
112
|
+
configdirector environments list
|
|
113
|
+
configdirector configs list [--tag <name>] [--untagged] [--state <state>]
|
|
114
|
+
configdirector configs get <key>
|
|
115
|
+
configdirector configs activity <key>
|
|
116
|
+
configdirector segments list
|
|
117
|
+
configdirector segments get <key>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`projects list` lists your organization's projects with their slugs and names, whichever project is selected. The other commands read the project from `--project`, `CONFIGDIRECTOR_PROJECT` or `configdirector.json`, as `scan` does:
|
|
121
|
+
|
|
122
|
+
- `environments list` lists the environments with their slugs and names, marking the live ones.
|
|
123
|
+
- `configs list` lists the configs with their type, role, lifetime and lifecycle state. `--tag <name>`, repeatable, lists the configs that have any of the tags; `--untagged` lists the configs without tags and cannot be combined with `--tag`; `--state` lists the configs in one lifecycle state: `new`, `in-use`, `settled`, `archive-ready` or `stale`. A tag name no tag has exits with 2.
|
|
124
|
+
- `configs get <key>` shows the config's settings, including its type's constraints, then each environment's targeting rules in order, written as `evaluate` writes them, with the default targeting rule value last. An old key works, and the output then starts with a line naming the current key.
|
|
125
|
+
- `configs activity <key>` shows when SDKs last evaluated the config, one line per environment, SDK key kind, SDK name and SDK version, with the time in UTC.
|
|
126
|
+
- `segments list` lists the segments with how many configs use each, and `segments get <key>` shows a segment's condition groups and its environment overrides.
|
|
127
|
+
|
|
128
|
+
```txt
|
|
129
|
+
new-checkout
|
|
130
|
+
Description: Shows the new checkout flow
|
|
131
|
+
Type: boolean
|
|
132
|
+
Role: flag
|
|
133
|
+
Lifetime: temporary
|
|
134
|
+
Availability: client and server SDKs
|
|
135
|
+
Lifecycle state: in-use
|
|
136
|
+
Tags: checkout
|
|
137
|
+
|
|
138
|
+
test
|
|
139
|
+
Default targeting rule: false
|
|
140
|
+
|
|
141
|
+
production (live)
|
|
142
|
+
1. plan is one of pro, team: true
|
|
143
|
+
2. 30% get true, 70% get false
|
|
144
|
+
3. in segment Beta testers: true
|
|
145
|
+
Default targeting rule: false
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
With `--json`, each prints the Admin API's response as received, except `configs list --state`, which prints only the configs in that state. A key no config or segment has exits with 2.
|
|
149
|
+
|
|
150
|
+
`projects list` needs `projects:read`. The others need `projects:read` to find the project, and `environments list` needs `environments:read`, `configs list`, `configs get` and `configs activity` need `configs:read`, plus `tags:read` for `--tag`, and `segments list` and `segments get` need `segments:read`. Without `segments:read`, `configs get` shows a segment condition's segment ID instead of its name; without `environments:read`, `segments get` names an override's environment by its ID instead of its slug.
|
|
151
|
+
|
|
152
|
+
## Create a config
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
configdirector configs create --key new-checkout --type boolean --role flag --lifetime temporary --default-value false
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`configs create` creates a config from options that match the Admin API's fields one to one, with no guessing and no prompts:
|
|
159
|
+
|
|
160
|
+
```txt
|
|
161
|
+
Created new-checkout in web-app: boolean, flag, temporary, client and server SDKs.
|
|
162
|
+
Default targeting rule in every environment: false
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
- `--key`, `--type` (`boolean`, `string`, `integer`, `float`, `timespan`, `enum`, `url` or `json`), `--role` (`config`, `flag`, `kill-switch` or `experiment`), `--lifetime` (`temporary` or `permanent`) and `--default-value` are required. `--default-value` is the default targeting rule value every environment starts with, not the in-code default value an application passes to the SDK.
|
|
166
|
+
- `--description <text>`; `--client-only` or `--server-only`, without which client and server SDKs both receive the config; `--tag <name>`, repeatable, naming an existing tag of the project; and `--variation <name=value>`, repeatable, for an experiment's variations.
|
|
167
|
+
- The values of `--default-value` and `--variation` are read in the config's type: `true` or `false`, a number for an integer, float or timespan, the text as written for a string, enum or URL, and JSON for a JSON config, with `@file` reading it from a file. A value that does not fit the type is a usage error.
|
|
168
|
+
- Constraints, each accepted only by its types: `--min` and `--max` (a value may equal them) for an integer, float or timespan; `--exclusive-min` and `--exclusive-max` for an integer or float; `--unit` (`milliseconds`, `seconds` or `minutes`) and `--allow-fractions` for a timespan, which needs `--unit`, `--min` and `--max`; `--allowed-value`, repeatable, and `--enum-value-type string|number` (default `string`) for an enum; `--https-only` for a URL, without which any HTTP or HTTPS URL is accepted; and `--json-schema <file>` for a JSON config. An option of another type is a usage error naming the types it belongs to. A timespan without `--unit`, `--min` or `--max` is a usage error too.
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
configdirector configs create --key checkout-timeout --type timespan --role config --lifetime permanent \
|
|
172
|
+
--unit seconds --min 1 --max 120 --default-value 30 --server-only
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
When the project already has a config with the key, as its current key or an old one, nothing is created: the command prints that config's key, type, role, lifetime and lifecycle state, and exits with 1. When ConfigDirector refuses the config for another reason, it exits with 2 and lists the reasons. With `--json`, it prints the created config as received, or the existing config when the key is taken.
|
|
176
|
+
|
|
177
|
+
`configs create` needs `projects:read`, `configs:create`, and `configs:read` to show the config that already has the key; `--tag` also needs `tags:read` and `config-settings:update`. The config shows in the audit log with the source CLI.
|
|
178
|
+
|
|
179
|
+
## Change targeting rules
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
configdirector targeting-rules set new-checkout --environment production --rules rules.json
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
`targeting-rules set` replaces every targeting rule of the config in one environment with the rules in the file, or in stdin with `--rules -`:
|
|
186
|
+
|
|
187
|
+
```json
|
|
188
|
+
{
|
|
189
|
+
"defaultValue": false,
|
|
190
|
+
"rules": [
|
|
191
|
+
{
|
|
192
|
+
"type": "conditional",
|
|
193
|
+
"order": 0,
|
|
194
|
+
"conditions": [
|
|
195
|
+
{
|
|
196
|
+
"kind": "attribute",
|
|
197
|
+
"attribute": "traits",
|
|
198
|
+
"trait": "/plan",
|
|
199
|
+
"operator": "is one of",
|
|
200
|
+
"targetType": "text",
|
|
201
|
+
"targetValues": ["pro", "team"]
|
|
202
|
+
}
|
|
203
|
+
],
|
|
204
|
+
"target": "value",
|
|
205
|
+
"value": true
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
- The file holds `defaultValue`, the default targeting rule value, and `rules`, exactly as the Admin API takes them. An environment's entry of `targets` in `configs get --json` has that shape, so you can edit it and write it back. Rules left out of the file are removed.
|
|
212
|
+
- A rule, condition or percentage without an `id` gets a new one, and the IDs given are kept.
|
|
213
|
+
- The CLI checks only that the file holds a JSON object. ConfigDirector checks the rules, and when it refuses them the command exits with 2 and lists its reasons.
|
|
214
|
+
- It asks for no confirmation and treats a live environment like any other. It prints what it wrote: `Replaced the targeting rules of new-checkout in production with 1 rule and the default targeting rule value false.` With `--json`, it prints the request it sent, with the IDs it gave.
|
|
215
|
+
|
|
216
|
+
`targeting-rules reference` prints the format: notes on how rules are evaluated, the condition kinds, the attributes a condition can test, and the operators for context kinds, segments and each target type. With `--json`, it prints the whole document as received, including the JSON Schema of the request `targeting-rules set` sends. Its notes name the MCP server's tools: `update_targeting_rules` is what `targeting-rules set` does, and `get_config` what `configs get` does.
|
|
217
|
+
|
|
218
|
+
`targeting-rules set` needs `projects:read`, `environments:read` and `config-targeting-rules:update`. `targeting-rules reference` needs only a valid token and no project.
|
|
219
|
+
|
|
77
220
|
## Options
|
|
78
221
|
|
|
79
|
-
| Option | Environment variable | Meaning
|
|
80
|
-
| ------------------ | ------------------------- |
|
|
81
|
-
| `--token <token>` | `CONFIGDIRECTOR_TOKEN` | API token. Without either, the token saved by `login` is used.
|
|
82
|
-
| `--base-url <url>` | `CONFIGDIRECTOR_BASE_URL` | API host. Defaults to `https://api.configdirector.com`.
|
|
83
|
-
| `--project <slug>` | `CONFIGDIRECTOR_PROJECT` | Project slug. Without either,
|
|
84
|
-
| `--json` | | Print JSON on stdout. Errors always go to stderr.
|
|
222
|
+
| Option | Environment variable | Meaning |
|
|
223
|
+
| ------------------ | ------------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
224
|
+
| `--token <token>` | `CONFIGDIRECTOR_TOKEN` | API token. Without either, the token saved by `login` is used. |
|
|
225
|
+
| `--base-url <url>` | `CONFIGDIRECTOR_BASE_URL` | API host. Defaults to `https://api.configdirector.com`. |
|
|
226
|
+
| `--project <slug>` | `CONFIGDIRECTOR_PROJECT` | Project slug. Without either, every command that reads a project uses the `project` in `configdirector.json`. |
|
|
227
|
+
| `--json` | | Print JSON on stdout. Errors always go to stderr. |
|
|
85
228
|
|
|
86
|
-
The command exits with 0 when it succeeds, 1 when `validate` found a problem, and 2 when it could not run: a usage mistake, a rejected token, a suspended service or an
|
|
229
|
+
The command exits with 0 when it succeeds, 1 when `validate` found a problem or `configs create` found a config that already has the key, and 2 when it could not run: a usage mistake, a rejected token, a suspended service, an unreachable API, or something the command names that does not exist, such as a config key, an environment, a saved context, a segment key or a tag. A CI job can therefore tell a wrong config key from an outage.
|
|
87
230
|
|
|
88
231
|
## License
|
|
89
232
|
|