configorama 0.11.2 → 1.0.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.
Files changed (52) hide show
  1. package/README.md +429 -123
  2. package/cli.js +282 -49
  3. package/index.d.ts +43 -1
  4. package/package.json +5 -1
  5. package/src/capabilities.js +59 -0
  6. package/src/capabilities.test.js +44 -0
  7. package/src/display.js +70 -7
  8. package/src/display.test.js +82 -0
  9. package/src/errors.js +73 -0
  10. package/src/index.js +91 -1
  11. package/src/main.js +117 -15
  12. package/src/resolvers/valueFromEval.js +11 -1
  13. package/src/resolvers/valueFromFile.js +5 -0
  14. package/src/resolvers/valueFromGit.js +43 -17
  15. package/src/resolvers/valueFromOptions.js +5 -4
  16. package/src/utils/filters/filterArgs.js +57 -0
  17. package/src/utils/filters/oneOf.js +77 -0
  18. package/src/utils/introspection/audit.js +78 -0
  19. package/src/utils/introspection/graph.js +43 -0
  20. package/src/utils/introspection/model.js +150 -0
  21. package/src/utils/introspection/model.test.js +93 -0
  22. package/src/utils/parsing/commentAnnotations.js +107 -0
  23. package/src/utils/parsing/commentAnnotations.test.js +123 -0
  24. package/src/utils/parsing/enrichMetadata.js +64 -1
  25. package/src/utils/parsing/enrichMetadata.test.js +84 -0
  26. package/src/utils/parsing/extractComment.js +145 -0
  27. package/src/utils/parsing/extractComment.test.js +182 -0
  28. package/src/utils/parsing/preProcess.js +2 -1
  29. package/src/utils/paths/findLineForKey.js +2 -2
  30. package/src/utils/paths/ignorePaths.js +21 -9
  31. package/src/utils/redaction/redact.js +78 -0
  32. package/src/utils/redaction/redact.test.js +38 -0
  33. package/src/utils/redaction/setupRedaction.js +47 -0
  34. package/src/utils/redaction/setupRedaction.test.js +68 -0
  35. package/src/utils/requirements/configRequirements.js +351 -0
  36. package/src/utils/requirements/configRequirements.test.js +380 -0
  37. package/src/utils/requirements/serializeRequirements.js +120 -0
  38. package/src/utils/requirements/serializeRequirements.test.js +211 -0
  39. package/src/utils/security/evalSafety.js +86 -0
  40. package/src/utils/security/evalSafety.test.js +61 -0
  41. package/src/utils/security/safetyPolicy.js +110 -0
  42. package/src/utils/security/safetyPolicy.test.js +29 -0
  43. package/src/utils/strings/didYouMean.js +70 -0
  44. package/src/utils/strings/didYouMean.test.js +52 -0
  45. package/src/utils/strings/formatFunctionArgs.js +6 -1
  46. package/src/utils/strings/splitByComma.js +5 -0
  47. package/src/utils/ui/configWizard.js +208 -34
  48. package/src/utils/ui/createEditorLink.js +17 -1
  49. package/src/utils/ui/promptDescriptors.js +196 -0
  50. package/src/utils/ui/promptDescriptors.test.js +162 -0
  51. package/src/utils/variables/cleanVariable.js +22 -0
  52. package/src/utils/variables/getVariableType.js +1 -0
package/README.md CHANGED
@@ -1,8 +1,90 @@
1
1
  # Configorama
2
2
 
3
- Dynamic configuration values with variable support for yml, json, toml, hcl (Terraform), and other config formats.
3
+ [![npm version](https://img.shields.io/npm/v/configorama.svg)](https://www.npmjs.com/package/configorama)
4
+ [![license](https://img.shields.io/npm/l/configorama.svg)](https://www.npmjs.com/package/configorama)
5
+ [![types](https://img.shields.io/npm/types/configorama.svg)](https://www.npmjs.com/package/configorama)
4
6
 
5
- Configorama extends your configuration with a powerful variable system that resolves values from CLI options, environment variables, file references, TypeScript/JavaScript files, git data, self-references, conditional expressions, and any custom source you define.
7
+ Resolve dynamic config values from environment variables, CLI flags, files, git data, expressions, and custom sources. Works with YAML, JSON, TOML, INI, HCL, Markdown, JavaScript, and TypeScript.
8
+
9
+ ```bash
10
+ npm install configorama
11
+ npx configorama config.yml --stage prod
12
+ ```
13
+
14
+ Configorama is a framework-agnostic variable engine for configuration files. Use it to resolve a config at runtime, inspect missing values before resolution, audit risky references, draw dependency graphs, run an interactive setup flow, or emit requirements JSON for agents and automation.
15
+
16
+ ## TL;DR
17
+
18
+ Deployment configs usually pull values from several places: env vars, CLI flags, local files, generated JavaScript, git metadata, stage-specific maps, and secret stores. Most config parsers stop at parsing, while framework-specific variable systems tend to stay tied to that framework.
19
+
20
+ Configorama loads a config file, finds variable references, resolves them in dependency order, applies filters/functions, and returns a plain JavaScript object. It can also report what the config needs before resolution.
21
+
22
+ Common use cases:
23
+
24
+ | Need | Support | Example |
25
+ |---|---|---|
26
+ | Resolve values from many sources | Built-in `env`, `option`/`opt`, `self`, `file`, `text`, `git`, `cron`, `eval`, and `if` sources | `${env:API_KEY}`, `${option:stage}`, `${file(./secrets.yml)}` |
27
+ | Keep config portable | Runs outside any framework | Use the same resolver in a CLI, build script, deploy job, or app bootstrap |
28
+ | Prompt for missing inputs | Interactive setup wizard with type-aware prompts and masked secrets | `configorama setup config.yml` |
29
+ | Tell agents what to provide | Requirements JSON with `schemaVersion`, `requirements[]`, and `ask[]` | `configorama inspect config.yml --view requirements` |
30
+ | Inspect before resolving | Full inspection model plus focused `requirements`, `audit`, and `graph` views | `configorama inspect config.yml` |
31
+ | Document variables near the config | `help()` plus comment annotations for descriptions, obtain hints, examples, groups, sensitivity, and deprecation warnings | `# @from Stripe dashboard > Developers > API keys` |
32
+ | Enforce runtime constraints | Type filters and `oneOf(...)` validation | `${option:threads \| Number \| oneOf(1, 2, 4)}` |
33
+
34
+ ## Quick Example
35
+
36
+ ```yaml
37
+ # config.yml
38
+ service: billing-api
39
+
40
+ # Deployment stage
41
+ stage: ${option:stage | oneOf("dev", "staging", "prod")}
42
+
43
+ secrets:
44
+ # Stripe live secret key
45
+ # @from Stripe dashboard > Developers > API keys
46
+ # @example sk_live_...
47
+ # @sensitive true
48
+ # @group Payments
49
+ stripeSecret: ${env:STRIPE_SECRET_KEY}
50
+
51
+ database:
52
+ host: ${env:DB_HOST, "localhost"}
53
+ port: ${env:DB_PORT, 5432 | Number}
54
+ name: ${self:service}-${self:stage}
55
+ ```
56
+
57
+ ```bash
58
+ # Resolve the config
59
+ STRIPE_SECRET_KEY=sk_live_xxx npx configorama config.yml --stage prod
60
+
61
+ # Walk through missing variables interactively
62
+ npx configorama setup config.yml
63
+
64
+ # Print requirements for agents or automation
65
+ npx configorama inspect config.yml --view requirements
66
+
67
+ # Inspect requirements, dependency graph, and audit report together
68
+ npx configorama inspect config.yml
69
+ ```
70
+
71
+ ## What We Added Recently
72
+
73
+ | Area | Added |
74
+ |---|---|
75
+ | Normalized requirements model | `ConfigRequirements` groups occurrences by variable, normalizes `${opt:...}` and `${option:...}` as `variableType: "option"`, and tracks paths, defaults, types, allowed values, sensitivity, and conflicts. |
76
+ | Unified inspection CLI | `configorama inspect config.yml` emits requirements, graph, and audit output without resolving missing values. Use `--view requirements`, `--view audit`, or `--view graph` for one slice. |
77
+ | Requirements JSON | `configorama inspect config.yml --view requirements`, `configorama requirements config.yml`, and `configorama config.yml --requirements` emit `schemaVersion: 1`, `summary`, `requirements[]`, and environment-aware `ask[]`. |
78
+ | Safe inspection | `inspect`, `audit`, and `graph` run in safe mode by default. Use `--unsafe` to opt out or `--safe-root <dir>` to restrict file/text references. |
79
+ | Agent-friendly CLI contract | `configorama capabilities` prints commands, aliases, formats, flags, error codes, and exit codes as JSON. |
80
+ | Path extraction polish | Jq-style paths, `--raw`, and `--copy` make scalar extraction usable in scripts: `configorama -r --copy config.yml .database.host`. |
81
+ | Conflict handling | Conflicting type/default/allowed-value/annotation metadata is deterministic in the wizard. Requirements serialization fails on conflicts so agents get a clean contract. |
82
+ | Setup wizard migration | The wizard now consumes prompt descriptors derived from the requirements model, supports enum selects from `oneOf`, displays annotation details, and redacts sensitive values in setup summaries and setup stdout. |
83
+ | `oneOf(...)` validation | Runtime filter for inline literal sets and resolved list variables, including type-filter-first behavior such as `${option:threads \| Number \| oneOf(1, 2, 4)}`. |
84
+ | More type filters | `Array` and `Object` filters now validate/coerce arrays, comma-separated lists, JSON/JSON5 arrays, and JSON/JSON5 objects. |
85
+ | Option alias | `${option:name}` is supported alongside the existing `${opt:name}` shorthand. |
86
+ | Comment metadata | Leading/inline comments become help fallback; structured tags add `@description`, `@from`, `@example`, `@default`, `@sensitive`, `@group`, and `@deprecated`. |
87
+ | Structured CLI errors | Inspection commands default to JSON errors on stderr; `--error-format human` is available for terminal use. |
6
88
 
7
89
  ## Key Features
8
90
 
@@ -11,8 +93,10 @@ Configorama extends your configuration with a powerful variable system that reso
11
93
  - **Async/sync function execution** - Import and execute JavaScript/TypeScript files with argument passing
12
94
  - **Self-referencing** - Reference other values within the same config using dot notation
13
95
  - **Custom variable sources** - Pluggable architecture to add your own variable resolvers
14
- - **Filters and functions** - Transform and combine values with built-in or custom operators
15
- - **Metadata extraction** - Analyze configs without resolving them, or get full resolution history
96
+ - **Filters and functions** - Transform, coerce, constrain, and combine values with built-in or custom operators
97
+ - **Inspection modes** - Prompt humans interactively, generate requirements JSON, audit risky references, or output dependency graphs
98
+ - **Comment annotations** - Keep human and agent metadata beside the config value it describes
99
+ - **Metadata extraction** - Analyze configs without resolving missing values, or get full resolution history
16
100
  - **Circular dependency detection** - Helpful error messages instead of infinite loops
17
101
  - **TypeScript support** - Full type definitions and TypeScript file execution via tsx/ts-node
18
102
 
@@ -22,6 +106,9 @@ Configorama extends your configuration with a powerful variable system that reso
22
106
  <details>
23
107
  <summary>Click to expand</summary>
24
108
 
109
+ - [TL;DR](#tldr)
110
+ - [Quick Example](#quick-example)
111
+ - [What We Added Recently](#what-we-added-recently)
25
112
  - [Key Features](#key-features)
26
113
  - [Getting Started](#getting-started)
27
114
  - [Installation](#installation)
@@ -57,7 +144,8 @@ Configorama extends your configuration with a powerful variable system that reso
57
144
  - [API Reference](#api-reference)
58
145
  - [Async API](#async-api)
59
146
  - [Sync API](#sync-api)
60
- - [Analyze API](#analyze-api)
147
+ - [Library API](#library-api)
148
+ - [Inspect API](#inspect-api)
61
149
  - [Format Utilities](#format-utilities)
62
150
  - [Markdown Files](#markdown-files)
63
151
  - [`buildVariableSyntax(prefix, suffix, excludePatterns?)`](#buildvariablesyntaxprefix-suffix-excludepatterns)
@@ -72,6 +160,9 @@ Configorama extends your configuration with a powerful variable system that reso
72
160
  - [Custom Variable Sources](#custom-variable-sources)
73
161
  - [Variable Source Types](#variable-source-types)
74
162
  - [Creating a Custom Resolver](#creating-a-custom-resolver)
163
+ - [Config Wizard (Experimental)](#config-wizard-experimental)
164
+ - [Agent Requirements JSON](#agent-requirements-json)
165
+ - [Runtime Inspection](#runtime-inspection)
75
166
  - [CLI Usage](#cli-usage)
76
167
  - [Basic Commands](#basic-commands)
77
168
  - [Command Options](#command-options)
@@ -82,7 +173,6 @@ Configorama extends your configuration with a powerful variable system that reso
82
173
  - [Writing Tests](#writing-tests)
83
174
  - [Deployment](#deployment)
84
175
  - [Using with Serverless Framework](#using-with-serverless-framework)
85
- - [Docker Deployment](#docker-deployment)
86
176
  - [CI/CD Integration](#cicd-integration)
87
177
  - [Troubleshooting](#troubleshooting)
88
178
  - [Common Issues](#common-issues)
@@ -372,14 +462,14 @@ If your config is slow, please open an issue with the config (or a redacted repr
372
462
 
373
463
  ## Variable Sources
374
464
 
375
- Configorama supports multiple variable sources out of the box. All variable syntax follows the pattern `${type:value}` or `${type(value)}`.
465
+ Configorama supports multiple variable sources. All variable syntax follows the pattern `${type:value}` or `${type(value)}`.
376
466
 
377
467
  ### Summary Table
378
468
 
379
469
  | Variable | Syntax | Description | Example |
380
470
  |----------|-----------------------|------------------------|---------|
381
471
  | env | `${env:VAR}` | Environment variables | `${env:NODE_ENV}` |
382
- | opt | `${opt:flag}` | CLI option flags | `${opt:stage}` |
472
+ | option | `${option:flag}` or `${opt:flag}` | CLI option flags (`opt` is shorthand) | `${option:stage}` |
383
473
  | param | `${param:key}` | Parameter values | `${param:domain}` |
384
474
  | self | `${key}` or `${self:key}` | Self references | `${database.host}` |
385
475
  | file | `${file(path)}` | File references | `${file(./secrets.yml)}` |
@@ -753,7 +843,7 @@ The `ctx` parameter (always the last argument) provides access to:
753
843
  |----------|-------------|
754
844
  | `originalConfig` | The original unresolved configuration object |
755
845
  | `currentConfig` | The current (partially resolved) configuration |
756
- | `options` | Options passed to configorama (populates `${opt:xyz}` variables) |
846
+ | `options` | Options passed to configorama (populates `${option:xyz}` / `${opt:xyz}` variables) |
757
847
 
758
848
  **TypeScript users can import the type:**
759
849
 
@@ -943,7 +1033,7 @@ functions:
943
1033
  - Support for both sync and async TypeScript functions
944
1034
  - Function argument passing via config variables
945
1035
  - Full TypeScript interface support
946
- - Comprehensive error handling with helpful dependency messages
1036
+ - Errors point to the failing dependency
947
1037
 
948
1038
  ---
949
1039
 
@@ -1176,7 +1266,7 @@ aboveThreshold: ${eval(${value} > ${threshold})} # true
1176
1266
 
1177
1267
  ### If Expressions
1178
1268
 
1179
- Conditional expressions using ternary syntax. This is an alias for `eval` with a more intuitive name for conditionals.
1269
+ Conditional expressions using ternary syntax. This is an alias for `eval` with a clearer name for conditionals.
1180
1270
 
1181
1271
  ```yaml
1182
1272
  # Basic ternary (condition ? "yes" : "no")
@@ -1283,6 +1373,65 @@ serviceSlug: ${serviceName | toKebabCase} # 'my-service-name'
1283
1373
  - `toLowerCase` - Convert to lowercase
1284
1374
  - `toKebabCase` - Convert to kebab-case
1285
1375
  - `toCamelCase` - Convert to camelCase
1376
+ - `String`, `Number`, `Boolean`, `Array`, `Object`, `Json` - Validate/coerce resolved values
1377
+ - `oneOf(...)` - Restrict a value to inline literals or a resolved list variable
1378
+ - `help('text')` - Attach guidance to a variable for the [config wizard](#config-wizard-experimental); returns the value unchanged
1379
+
1380
+ The `help()` filter is an identity filter: it leaves the value untouched but records prompt/agent description text.
1381
+
1382
+ ```yaml
1383
+ apiKey: ${env:API_KEY | help('The Stripe live secret key')}
1384
+ stage: ${option:stage | toUpperCase | help('Deployment stage')}
1385
+ dbPort: ${env:DB_PORT, 5432 | Number | help('The Postgres port')}
1386
+ ```
1387
+
1388
+ `oneOf()` is a runtime constraint. It throws if the resolved value is not in the allowed set. Put type filters first when coercion matters:
1389
+
1390
+ ```yaml
1391
+ stage: ${option:stage | oneOf('dev', 'staging', 'prod')}
1392
+ threads: ${option:threads | Number | oneOf(1, 2, 4)}
1393
+
1394
+ allowedStages:
1395
+ - dev
1396
+ - prod
1397
+ stageFromList: ${option:stage | oneOf(${self:allowedStages})}
1398
+ ```
1399
+
1400
+ `Array` accepts existing arrays, JSON/JSON5 array strings, and comma-separated text. `Object` accepts existing objects and JSON/JSON5 object strings.
1401
+
1402
+ Comments are used as help fallback when `help()` is absent. Precedence is `help()` first, then trailing inline comments, then a leading comment block:
1403
+
1404
+ ```yaml
1405
+ # Used by deploy jobs
1406
+ deployToken: ${env:DEPLOY_TOKEN}
1407
+ region: ${option:region, 'us-east-1'} # AWS region
1408
+ ```
1409
+
1410
+ Use comment annotations for human and agent metadata. Filters affect runtime values; comments describe values:
1411
+
1412
+ ```yaml
1413
+ secrets:
1414
+ # Stripe live secret key
1415
+ # @from Stripe dashboard > Developers > API keys
1416
+ # @example sk_live_...
1417
+ # @default Set in CI or local shell profile
1418
+ # @sensitive true
1419
+ # @group Payments
1420
+ # @deprecated Use STRIPE_RESTRICTED_KEY instead
1421
+ stripeSecret: ${env:STRIPE_SECRET_KEY}
1422
+ ```
1423
+
1424
+ Supported annotation tags:
1425
+
1426
+ - `@description ...` - Explicit description; overrides normal comment text and `help()`
1427
+ - `@from ...` - Where to obtain the value; appears as `obtainHint`
1428
+ - `@example ...` - Example value; can appear multiple times
1429
+ - `@default ...` - Documentation-only default hint; does not resolve the variable
1430
+ - `@sensitive true|false` - Override name-based masking detection
1431
+ - `@group ...` - Wizard display group label
1432
+ - `@deprecated ...` - Warning text for requirements JSON and prompt descriptors
1433
+
1434
+ `from()` and `meta()` are not built-in filters. JSON files cannot use comment annotations because JSON has no comments; use JSON5/JSONC or another commented format if metadata is needed.
1286
1435
 
1287
1436
  **Custom filters:**
1288
1437
 
@@ -1519,62 +1668,87 @@ const config = configorama.sync('./config.yml', {
1519
1668
 
1520
1669
  ---
1521
1670
 
1522
- ### Analyze API
1671
+ ### Library API
1672
+
1673
+ ```javascript
1674
+ const configorama = require('configorama')
1675
+
1676
+ const config = await configorama('config.yml')
1677
+ const result = await configorama('config.yml', { returnMetadata: true })
1678
+ const requirements = await configorama.inspect('config.yml', { view: 'requirements' })
1679
+ const graph = await configorama.inspect('config.yml', { view: 'graph', format: 'mermaid' })
1680
+ const configSync = configorama.sync('config.yml')
1681
+ ```
1682
+
1683
+ The stable public surface is intentionally small:
1684
+
1685
+ | Method | Use it for |
1686
+ |---|---|
1687
+ | `configorama(fileOrObject, opts)` | Async resolution. Set `returnMetadata: true` when you need `metadata.variables`, `metadata.uniqueVariables`, or `metadata.fileDependencies`. |
1688
+ | `configorama.sync(fileOrObject, opts)` | Synchronous resolution for blocking contexts. |
1689
+ | `configorama.inspect(fileOrObject, opts)` | Pre-resolution inspection. Use `view: "requirements"`, `view: "audit"`, or `view: "graph"` for one projection. |
1690
+ | `configorama.format` | Parser utilities for YAML, JSON/JSON5, TOML, INI, HCL, and Markdown frontmatter. |
1691
+
1692
+ Lower-level helpers still exist for compatibility: `analyze()`, `introspect()`, `audit()`, `graph()`, `buildVariableSyntax()`, and `Configorama`. New code should start with `configorama()`, `configorama.sync()`, or `configorama.inspect()`.
1693
+
1694
+ `returnMetadata: true` remains the right API for tools that need resolved config plus dependency metadata:
1695
+
1696
+ ```javascript
1697
+ const result = await configorama('serverless.yml', {
1698
+ returnMetadata: true,
1699
+ allowUnknownVariableTypes: true,
1700
+ allowUnresolvedVariables: true,
1701
+ options: { stage: 'prod' }
1702
+ })
1703
+
1704
+ console.log(result.config)
1705
+ console.log(result.metadata.variables)
1706
+ console.log(result.metadata.uniqueVariables)
1707
+ console.log(result.metadata.fileDependencies.resolvedPaths)
1708
+ console.log(result.metadata.fileDependencies.globPatterns)
1709
+ ```
1710
+
1711
+ That metadata shape is the same path used by the newer inspection APIs, so tools can keep consuming it without switching to `inspect()`.
1712
+
1713
+ ---
1714
+
1715
+ ### Inspect API
1523
1716
 
1524
- Analyze config structure without resolving variables.
1717
+ Inspect config structure without resolving missing user inputs.
1525
1718
 
1526
1719
  **Signature:**
1527
1720
 
1528
1721
  ```typescript
1529
- function configorama.analyze(
1722
+ function configorama.inspect(
1530
1723
  configPathOrObject: string | object,
1531
- settings?: ConfigoramaSettings
1532
- ): Promise<AnalyzeResult>
1724
+ settings?: ConfigoramaSettings & {
1725
+ view?: 'requirements' | 'audit' | 'graph'
1726
+ format?: 'json' | 'mermaid' | 'dot'
1727
+ }
1728
+ ): Promise<object | string>
1533
1729
  ```
1534
1730
 
1535
- **Returns:**
1731
+ With no `view`, `inspect()` returns the full model:
1536
1732
 
1537
- ```typescript
1538
- interface AnalyzeResult {
1539
- originalConfig: object // Raw config object
1540
- variables: Variable[] // All variables found
1541
- uniqueVariables: Record<string, Variable[]> // Variables grouped by name
1542
- fileDependencies: string[] // File references
1543
- }
1733
+ ```javascript
1734
+ const model = await configorama.inspect('./config.yml')
1544
1735
 
1545
- interface Variable {
1546
- variable: string // Full variable syntax (e.g., '${env:KEY}')
1547
- variableType: string // Type (e.g., 'env', 'opt', 'file')
1548
- variableName: string // Name/path (e.g., 'KEY')
1549
- variablePath: string // Location in config (e.g., 'database.host')
1550
- defaultValue: any // Default value if provided
1551
- hasDefault: boolean // Whether default exists
1552
- }
1736
+ console.log(model.requirements)
1737
+ console.log(model.graph)
1738
+ console.log(model.audit)
1553
1739
  ```
1554
1740
 
1555
- **Example:**
1741
+ Use `view` for one projection:
1556
1742
 
1557
1743
  ```javascript
1558
1744
  const configorama = require('configorama')
1559
1745
 
1560
- const analysis = await configorama.analyze('./config.yml')
1561
-
1562
- console.log(`Found ${analysis.variables.length} variables`)
1563
- console.log(`File dependencies:`, analysis.fileDependencies)
1564
-
1565
- // List all environment variables required
1566
- const envVars = analysis.variables
1567
- .filter(v => v.variableType === 'env' && !v.hasDefault)
1568
- .map(v => v.variableName)
1569
-
1570
- console.log('Required env vars:', envVars)
1746
+ const requirements = await configorama.inspect('./config.yml', { view: 'requirements' })
1747
+ const audit = await configorama.inspect('./config.yml', { view: 'audit' })
1748
+ const graph = await configorama.inspect('./config.yml', { view: 'graph', format: 'mermaid' })
1571
1749
  ```
1572
1750
 
1573
- **Use cases:**
1574
- - Generate documentation of required environment variables
1575
- - Validate config structure in CI/CD
1576
- - Build dependency graphs
1577
- - Audit external dependencies before resolution
1751
+ The older `analyze()`, `introspect()`, `audit()`, and `graph()` helpers map to the same underlying inspection paths. They are kept for existing consumers.
1578
1752
 
1579
1753
  ---
1580
1754
 
@@ -1882,7 +2056,7 @@ const config = await configorama(configFile, {
1882
2056
 
1883
2057
  | Option | Type | Default | Description |
1884
2058
  |--------|------|---------|-------------|
1885
- | `options` | `object` | `{}` | CLI options/flags to populate `${opt:xyz}` variables |
2059
+ | `options` | `object` | `{}` | CLI options/flags to populate `${option:xyz}` / `${opt:xyz}` variables |
1886
2060
  | `syntax` | `string \| RegExp` | `${...}` | Custom variable syntax regex pattern |
1887
2061
  | `configDir` | `string` | directory of config file | Working directory for relative file paths |
1888
2062
  | `variableSources` | `VariableSource[]` | `[]` | Custom variable sources (see below) |
@@ -1918,7 +2092,7 @@ const config = await configorama(configFile, {
1918
2092
 
1919
2093
  ## Custom Variable Sources
1920
2094
 
1921
- Configorama allows you to bring your own variable sources.
2095
+ Bring your own variable sources.
1922
2096
 
1923
2097
  ### Variable Source Types
1924
2098
 
@@ -1926,7 +2100,7 @@ The `source` property defines how the config wizard handles each variable type:
1926
2100
 
1927
2101
  | Source | Description | Wizard Behavior | Examples |
1928
2102
  |--------|-------------|-----------------|----------|
1929
- | `'user'` | Values provided by user at runtime | Prompt user for value | `env`, `opt` |
2103
+ | `'user'` | Values provided by user at runtime | Prompt user for value | `env`, `option` / `opt` |
1930
2104
  | `'config'` | Values from config files or self-references | Check existence, can create | `self`, `file`, `text` |
1931
2105
  | `'remote'` | Values from external services | Fetch, prompt if missing, can write back | `ssm`, `vault`, `consul` |
1932
2106
  | `'readonly'` | Computed or system-derived values | Display only, cannot modify | `git`, `cron`, `eval` |
@@ -1936,7 +2110,7 @@ The `source` property defines how the config wizard handles each variable type:
1936
2110
  | Variable | Source Type | Description |
1937
2111
  |----------|-------------|-------------|
1938
2112
  | `${env:VAR}` | `user` | Environment variables |
1939
- | `${opt:flag}` | `user` | CLI option flags |
2113
+ | `${option:flag}` / `${opt:flag}` | `user` | CLI option flags |
1940
2114
  | `${param:key}` | `user` | Parameter values |
1941
2115
  | `${self:key}` | `config` | Self references |
1942
2116
  | `${file(path)}` | `config` | File references |
@@ -2065,9 +2239,166 @@ database:
2065
2239
 
2066
2240
  ---
2067
2241
 
2242
+ ## Config Wizard (Experimental)
2243
+
2244
+ The config wizard walks you through every variable your config needs that isn't resolved yet, prompting for each one and then resolving the config with your answers.
2245
+
2246
+ Trigger it with the `--setup` flag, the `setup` subcommand, or the `setup` library option:
2247
+
2248
+ ```bash
2249
+ configorama config.yml --setup
2250
+ configorama setup config.yml
2251
+ ```
2252
+
2253
+ ```javascript
2254
+ const config = await configorama('config.yml', { setup: true })
2255
+ ```
2256
+
2257
+ The wizard groups unresolved variables by source and prompts for each:
2258
+
2259
+ - `${option:...}` / `${opt:...}` - CLI option flags (`opt` is shorthand)
2260
+ - `${env:...}` - environment variables (shows the current `process.env` value if set)
2261
+ - `${self:...}` and dot-prop references - values defined elsewhere in the config
2262
+
2263
+ Variables whose names look sensitive (`secret`, `password`, `token`, `key`, etc.) are prompted with a masked password input. Use comment annotations for new metadata, or annotate any variable with the backward-compatible [`help()` filter](#filters-experimental) to show guidance during the prompt:
2264
+
2265
+ ```yaml
2266
+ # Stripe live secret key
2267
+ # @from Stripe dashboard > Developers > API keys
2268
+ # @sensitive true
2269
+ apiKey: ${env:API_KEY}
2270
+
2271
+ stage: ${opt:stage | help('Deployment stage, e.g. dev or prod')}
2272
+ ```
2273
+
2274
+ The [Variable Source Types](#variable-source-types) table describes how the wizard treats each source.
2275
+
2276
+ > **Experimental:** the wizard fills in values for the current resolution run only. It does not write your answers back to the config file yet.
2277
+
2278
+ ---
2279
+
2280
+ ## Agent Requirements JSON
2281
+
2282
+ Use the requirements inspection view when an agent or script needs to know what a config is missing without running the full resolver:
2283
+
2284
+ ```bash
2285
+ configorama inspect config.yml --view requirements
2286
+ ```
2287
+
2288
+ The older `requirements` command and `--requirements` flag still work:
2289
+
2290
+ ```bash
2291
+ configorama requirements config.yml
2292
+ configorama config.yml --requirements
2293
+ ```
2294
+
2295
+ All three forms use analyze mode and print JSON. Missing required variables do not fail requirements output. The result is environment-aware: if `process.env.API_KEY` is already set, `${env:API_KEY}` is removed from `ask[]`.
2296
+
2297
+ ```json
2298
+ {
2299
+ "schemaVersion": 1,
2300
+ "config": "config.yml",
2301
+ "summary": {
2302
+ "total": 2,
2303
+ "required": 1,
2304
+ "optional": 1,
2305
+ "sensitive": 1
2306
+ },
2307
+ "requirements": [
2308
+ {
2309
+ "name": "API_KEY",
2310
+ "variable": "env:API_KEY",
2311
+ "variableType": "env",
2312
+ "sourceClass": "user",
2313
+ "type": "string",
2314
+ "description": "Stripe live secret key",
2315
+ "descriptionSource": "commentTag",
2316
+ "allowedValues": null,
2317
+ "sensitive": true,
2318
+ "sensitiveSource": "commentTag",
2319
+ "required": true,
2320
+ "default": null,
2321
+ "defaultHint": "Set in CI or local shell profile",
2322
+ "obtainHint": "Stripe dashboard > Developers > API keys",
2323
+ "examples": ["sk_live_..."],
2324
+ "group": "Payments",
2325
+ "deprecationMessage": "Use STRIPE_RESTRICTED_KEY instead",
2326
+ "paths": ["apiKey"],
2327
+ "conflicts": []
2328
+ }
2329
+ ],
2330
+ "ask": [
2331
+ {
2332
+ "name": "API_KEY",
2333
+ "variable": "env:API_KEY",
2334
+ "variableType": "env",
2335
+ "type": "string",
2336
+ "sensitive": true,
2337
+ "description": "Stripe live secret key",
2338
+ "obtainHint": "Stripe dashboard > Developers > API keys",
2339
+ "examples": ["sk_live_..."],
2340
+ "defaultHint": "Set in CI or local shell profile",
2341
+ "group": "Payments",
2342
+ "deprecationMessage": "Use STRIPE_RESTRICTED_KEY instead",
2343
+ "paths": ["apiKey"],
2344
+ "how": "Set environment variable API_KEY"
2345
+ }
2346
+ ]
2347
+ }
2348
+ ```
2349
+
2350
+ `variableType` uses normalized names. CLI flags are reported as `option` for both `${option:stage}` and the backward-compatible `${opt:stage}` shorthand. Concrete missing `${file(...)}` and `${text(...)}` dependencies appear in `ask[]`; dynamic paths such as `${file(./${option:stage}.yml)}` ask for the inner variables first.
2351
+
2352
+ ---
2353
+
2354
+ ## Runtime Inspection
2355
+
2356
+ `inspect` is the current CLI surface for pre-resolution analysis. It does not resolve missing user inputs. By default it returns the full model:
2357
+
2358
+ ```bash
2359
+ configorama inspect config.yml
2360
+ ```
2361
+
2362
+ ```json
2363
+ {
2364
+ "schemaVersion": 1,
2365
+ "config": "config.yml",
2366
+ "requirements": {},
2367
+ "graph": {},
2368
+ "audit": {}
2369
+ }
2370
+ ```
2371
+
2372
+ Use `--view` when a script wants one projection:
2373
+
2374
+ ```bash
2375
+ # Required inputs and ask[] contract
2376
+ configorama inspect config.yml --view requirements
2377
+
2378
+ # Static risk report for executable or external surfaces
2379
+ configorama inspect config.yml --view audit
2380
+
2381
+ # Dependency graph as JSON, Mermaid, or Graphviz DOT
2382
+ configorama inspect config.yml --view graph --format json
2383
+ configorama inspect config.yml --view graph --format mermaid
2384
+ configorama inspect config.yml --view graph --format dot
2385
+ ```
2386
+
2387
+ Inspection commands default to safe mode, which blocks executable and config-mutating surfaces during analysis. Use `--unsafe` only when you intentionally want the resolver to execute those surfaces during inspection. Use `--safe-root <dir>` or `--file-root <dir>` to restrict file and text references to known directories.
2388
+
2389
+ Agents can discover the CLI contract without scraping this README:
2390
+
2391
+ ```bash
2392
+ configorama capabilities
2393
+ ```
2394
+
2395
+ That command prints JSON containing the documented commands, compatibility aliases, views, output formats, flags, error codes, and exit codes.
2396
+
2397
+ ---
2398
+
2068
2399
  ## CLI Usage
2069
2400
 
2070
- Configorama includes a CLI tool for resolving configs from the command line.
2401
+ Configorama includes a CLI tool for resolving configs, extracting paths, and inspecting config requirements before resolution.
2071
2402
 
2072
2403
  ### Basic Commands
2073
2404
 
@@ -2087,6 +2418,29 @@ configorama config.yml --info
2087
2418
  # Verify config (check for errors without resolving)
2088
2419
  configorama config.yml --verify
2089
2420
 
2421
+ # Walk through unresolved variables interactively (experimental)
2422
+ configorama config.yml --setup
2423
+ configorama setup config.yml
2424
+
2425
+ # Inspect requirements, graph, and audit together
2426
+ configorama inspect config.yml
2427
+
2428
+ # Print agent requirements JSON without resolving missing values
2429
+ configorama inspect config.yml --view requirements
2430
+
2431
+ # Compatibility forms for requirements JSON
2432
+ configorama requirements config.yml
2433
+ configorama config.yml --requirements
2434
+
2435
+ # Audit risky references without resolving missing values
2436
+ configorama inspect config.yml --view audit
2437
+
2438
+ # Print a dependency graph
2439
+ configorama inspect config.yml --view graph --format mermaid
2440
+
2441
+ # Print the machine-readable CLI contract
2442
+ configorama capabilities
2443
+
2090
2444
  # Extract a specific path from config
2091
2445
  configorama config.yml .database.host
2092
2446
 
@@ -2105,20 +2459,37 @@ configorama config.yml --format yaml
2105
2459
  ```text
2106
2460
  Usage:
2107
2461
  configorama [options] <file> [path]
2462
+ configorama <command> <file> [options]
2463
+
2464
+ Commands:
2465
+ (default) Resolve <file> and print the result
2466
+ inspect <file> Introspect a config without resolving it
2467
+ --view requirements|audit|graph for one slice
2468
+ setup <file> Run the interactive config wizard (experimental)
2469
+ capabilities Print the machine-readable CLI contract as JSON
2108
2470
 
2109
2471
  Options:
2110
2472
  -h, --help Show this help message
2111
2473
  -v, --version Show version number
2112
2474
  -o, --output <file> Write output to file instead of stdout
2113
- -f, --format <format> Output format: json, yaml, or js (default: json)
2475
+ -f, --format <format> Output format: json, yaml, js (resolve);
2476
+ json, mermaid, dot (graph)
2477
+ --view <view> inspect view: requirements, audit, or graph
2114
2478
  -r, --raw Print extracted scalar values without JSON quoting
2115
2479
  -c, --copy Copy the formatted output to the clipboard
2116
2480
  -d, --debug Enable debug mode
2117
2481
  -i, --info Show info about the config
2118
2482
  -V, --verify Verify the config
2483
+ --safe Block executable/config-mutating surfaces during resolution
2484
+ --unsafe Disable inspect/audit/graph default safe inspection
2485
+ --safe-root <dir> Restrict file/text references to an allowed root
2486
+ --file-root <dir> Alias for --safe-root
2487
+ --error-format <fmt> Error format on stderr: json or human
2119
2488
  --param <key=value> Pass parameter values (can be used multiple times)
2120
2489
  --allow-unknown Allow unknown variables to pass through
2121
2490
  --allow-undefined Allow undefined values in the final output
2491
+ --setup Alias for configorama setup <file>
2492
+ --requirements Compatibility form for requirements JSON
2122
2493
 
2123
2494
  Path Extraction:
2124
2495
  configorama config.yml .database.host Extract a nested value
@@ -2139,6 +2510,8 @@ configorama config.yml .stage --raw
2139
2510
 
2140
2511
  `--copy` copies exactly the formatted value that the CLI prints. It uses native clipboard commands where available: `pbcopy` on macOS, `clip` on Windows, and `wl-copy`, `xclip`, or `xsel` on Linux.
2141
2512
 
2513
+ Structured commands (`inspect`, `requirements`, `audit`, `graph`, and `capabilities`) default to JSON errors on stderr. Use `--error-format human` for boxed terminal errors, or `--error-format json` to force machine-readable errors in resolve mode.
2514
+
2142
2515
  ### CLI Examples
2143
2516
 
2144
2517
  **Basic resolution:**
@@ -2424,73 +2797,6 @@ serverless deploy --stage prod --region us-west-2
2424
2797
 
2425
2798
  ---
2426
2799
 
2427
- ### Docker Deployment
2428
-
2429
- **Dockerfile:**
2430
-
2431
- ```dockerfile
2432
- FROM node:22-alpine
2433
-
2434
- WORKDIR /app
2435
-
2436
- # Copy package files
2437
- COPY package*.json ./
2438
-
2439
- # Install dependencies
2440
- RUN npm ci --only=production
2441
-
2442
- # Copy application files
2443
- COPY . .
2444
-
2445
- # Set environment variables (can be overridden at runtime)
2446
- ENV NODE_ENV=production
2447
- ENV STAGE=prod
2448
-
2449
- # Run config resolution at build time (optional)
2450
- # RUN node -e "require('configorama').sync('./config.yml', { options: { stage: process.env.STAGE } })"
2451
-
2452
- CMD ["node", "index.js"]
2453
- ```
2454
-
2455
- **docker-compose.yml:**
2456
-
2457
- ```yaml
2458
- version: '3.8'
2459
-
2460
- services:
2461
- app:
2462
- build: .
2463
- environment:
2464
- - NODE_ENV=production
2465
- - STAGE=prod
2466
- - DB_HOST=postgres
2467
- - DB_PASSWORD=${DB_PASSWORD}
2468
- - API_KEY=${API_KEY}
2469
- depends_on:
2470
- - postgres
2471
-
2472
- postgres:
2473
- image: postgres:15
2474
- environment:
2475
- POSTGRES_PASSWORD: ${DB_PASSWORD}
2476
- ```
2477
-
2478
- **Usage:**
2479
-
2480
- ```bash
2481
- # Build
2482
- docker build -t myapp .
2483
-
2484
- # Run with environment variables
2485
- docker run \
2486
- -e DB_HOST=mydb.example.com \
2487
- -e DB_PASSWORD=secret \
2488
- -e API_KEY=abc123 \
2489
- myapp
2490
- ```
2491
-
2492
- ---
2493
-
2494
2800
  ### CI/CD Integration
2495
2801
 
2496
2802
  **GitHub Actions example (.github/workflows/deploy.yml):**
@@ -2776,7 +3082,7 @@ Configorama detects circular dependencies and throws a helpful error instead of
2776
3082
 
2777
3083
  **Q: Why should I use this?**
2778
3084
 
2779
- Never render a stale configuration file again! Configorama ensures your configs are always up-to-date with the latest environment variables, CLI flags, file contents, and custom sources.
3085
+ Configs resolve fresh on every run, so values stay in sync with your environment variables, CLI flags, file contents, and custom sources instead of going stale.
2780
3086
 
2781
3087
  ---
2782
3088