@contentful/experience-design-system-cli 2.2.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/README.md +532 -0
- package/bin/cli.js +58 -0
- package/dist/package.json +56 -0
- package/dist/src/analyze/command.d.ts +3 -0
- package/dist/src/analyze/command.js +175 -0
- package/dist/src/analyze/extract/astro.d.ts +5 -0
- package/dist/src/analyze/extract/astro.js +280 -0
- package/dist/src/analyze/extract/pipeline.d.ts +6 -0
- package/dist/src/analyze/extract/pipeline.js +298 -0
- package/dist/src/analyze/extract/react.d.ts +2 -0
- package/dist/src/analyze/extract/react.js +1949 -0
- package/dist/src/analyze/extract/slot-detection.d.ts +35 -0
- package/dist/src/analyze/extract/slot-detection.js +101 -0
- package/dist/src/analyze/extract/stencil.d.ts +2 -0
- package/dist/src/analyze/extract/stencil.js +293 -0
- package/dist/src/analyze/extract/tsx-shared.d.ts +8 -0
- package/dist/src/analyze/extract/tsx-shared.js +263 -0
- package/dist/src/analyze/extract/vue-tsx.d.ts +2 -0
- package/dist/src/analyze/extract/vue-tsx.js +498 -0
- package/dist/src/analyze/extract/vue.d.ts +5 -0
- package/dist/src/analyze/extract/vue.js +647 -0
- package/dist/src/analyze/extract/web-components.d.ts +2 -0
- package/dist/src/analyze/extract/web-components.js +866 -0
- package/dist/src/analyze/pre-classify.d.ts +17 -0
- package/dist/src/analyze/pre-classify.js +144 -0
- package/dist/src/analyze/select/command.d.ts +2 -0
- package/dist/src/analyze/select/command.js +256 -0
- package/dist/src/analyze/select/index.d.ts +6 -0
- package/dist/src/analyze/select/index.js +5 -0
- package/dist/src/analyze/select/parser.d.ts +6 -0
- package/dist/src/analyze/select/parser.js +53 -0
- package/dist/src/analyze/select/persistence.d.ts +9 -0
- package/dist/src/analyze/select/persistence.js +42 -0
- package/dist/src/analyze/select/stdout.d.ts +7 -0
- package/dist/src/analyze/select/stdout.js +3 -0
- package/dist/src/analyze/select/tui/App.d.ts +8 -0
- package/dist/src/analyze/select/tui/App.js +491 -0
- package/dist/src/analyze/select/tui/components/ComponentDetail.d.ts +20 -0
- package/dist/src/analyze/select/tui/components/ComponentDetail.js +43 -0
- package/dist/src/analyze/select/tui/components/FieldEditor.d.ts +11 -0
- package/dist/src/analyze/select/tui/components/FieldEditor.js +531 -0
- package/dist/src/analyze/select/tui/components/FinalizeDialog.d.ts +10 -0
- package/dist/src/analyze/select/tui/components/FinalizeDialog.js +15 -0
- package/dist/src/analyze/select/tui/components/HelpOverlay.d.ts +7 -0
- package/dist/src/analyze/select/tui/components/HelpOverlay.js +11 -0
- package/dist/src/analyze/select/tui/components/JsonEditor.d.ts +11 -0
- package/dist/src/analyze/select/tui/components/JsonEditor.js +154 -0
- package/dist/src/analyze/select/tui/components/JsonPanel.d.ts +11 -0
- package/dist/src/analyze/select/tui/components/JsonPanel.js +62 -0
- package/dist/src/analyze/select/tui/components/PreviewSummaryBar.d.ts +8 -0
- package/dist/src/analyze/select/tui/components/PreviewSummaryBar.js +29 -0
- package/dist/src/analyze/select/tui/components/QuitDialog.d.ts +8 -0
- package/dist/src/analyze/select/tui/components/QuitDialog.js +14 -0
- package/dist/src/analyze/select/tui/components/Sidebar.d.ts +15 -0
- package/dist/src/analyze/select/tui/components/Sidebar.js +48 -0
- package/dist/src/analyze/select/tui/components/SourcePanel.d.ts +11 -0
- package/dist/src/analyze/select/tui/components/SourcePanel.js +52 -0
- package/dist/src/analyze/select/tui/components/StatusBar.d.ts +11 -0
- package/dist/src/analyze/select/tui/components/StatusBar.js +6 -0
- package/dist/src/analyze/select/tui/components/TopBar.d.ts +10 -0
- package/dist/src/analyze/select/tui/components/TopBar.js +5 -0
- package/dist/src/analyze/select/tui/hooks/useImmediateInput.d.ts +24 -0
- package/dist/src/analyze/select/tui/hooks/useImmediateInput.js +68 -0
- package/dist/src/analyze/select/tui/hooks/useKeymap.d.ts +24 -0
- package/dist/src/analyze/select/tui/hooks/useKeymap.js +67 -0
- package/dist/src/analyze/select/tui/hooks/useSession.d.ts +19 -0
- package/dist/src/analyze/select/tui/hooks/useSession.js +52 -0
- package/dist/src/analyze/select/tui/hooks/useUndo.d.ts +8 -0
- package/dist/src/analyze/select/tui/hooks/useUndo.js +26 -0
- package/dist/src/analyze/select/types.d.ts +46 -0
- package/dist/src/analyze/select/types.js +20 -0
- package/dist/src/analyze/select-agent/command.d.ts +2 -0
- package/dist/src/analyze/select-agent/command.js +208 -0
- package/dist/src/analyze/tui/AnalyzeView.d.ts +24 -0
- package/dist/src/analyze/tui/AnalyzeView.js +38 -0
- package/dist/src/apply/api-client.d.ts +35 -0
- package/dist/src/apply/api-client.js +143 -0
- package/dist/src/apply/command.d.ts +6 -0
- package/dist/src/apply/command.js +787 -0
- package/dist/src/apply/manifest.d.ts +1 -0
- package/dist/src/apply/manifest.js +1 -0
- package/dist/src/apply/tui/SelectView.d.ts +18 -0
- package/dist/src/apply/tui/SelectView.js +34 -0
- package/dist/src/apply/tui/ServerApplyView.d.ts +32 -0
- package/dist/src/apply/tui/ServerApplyView.js +42 -0
- package/dist/src/apply/tui/ServerPreviewView.d.ts +9 -0
- package/dist/src/apply/tui/ServerPreviewView.js +21 -0
- package/dist/src/credentials-store.d.ts +8 -0
- package/dist/src/credentials-store.js +30 -0
- package/dist/src/generate/agent-runner.d.ts +86 -0
- package/dist/src/generate/agent-runner.js +314 -0
- package/dist/src/generate/command.d.ts +2 -0
- package/dist/src/generate/command.js +545 -0
- package/dist/src/generate/edit/command.d.ts +2 -0
- package/dist/src/generate/edit/command.js +126 -0
- package/dist/src/generate/prompt-builder.d.ts +18 -0
- package/dist/src/generate/prompt-builder.js +202 -0
- package/dist/src/generate/tui/GenerateView.d.ts +12 -0
- package/dist/src/generate/tui/GenerateView.js +10 -0
- package/dist/src/import/command.d.ts +2 -0
- package/dist/src/import/command.js +96 -0
- package/dist/src/import/orchestrator.d.ts +37 -0
- package/dist/src/import/orchestrator.js +374 -0
- package/dist/src/import/path-utils.d.ts +15 -0
- package/dist/src/import/path-utils.js +30 -0
- package/dist/src/import/tui/WizardApp.d.ts +10 -0
- package/dist/src/import/tui/WizardApp.js +906 -0
- package/dist/src/import/tui/steps/CredentialsStep.d.ts +15 -0
- package/dist/src/import/tui/steps/CredentialsStep.js +79 -0
- package/dist/src/import/tui/steps/DoneStep.d.ts +20 -0
- package/dist/src/import/tui/steps/DoneStep.js +17 -0
- package/dist/src/import/tui/steps/ErrorStep.d.ts +8 -0
- package/dist/src/import/tui/steps/ErrorStep.js +11 -0
- package/dist/src/import/tui/steps/GateStep.d.ts +14 -0
- package/dist/src/import/tui/steps/GateStep.js +20 -0
- package/dist/src/import/tui/steps/GenerateReviewStep.d.ts +8 -0
- package/dist/src/import/tui/steps/GenerateReviewStep.js +208 -0
- package/dist/src/import/tui/steps/PathValidationStep.d.ts +10 -0
- package/dist/src/import/tui/steps/PathValidationStep.js +151 -0
- package/dist/src/import/tui/steps/PreviewStep.d.ts +21 -0
- package/dist/src/import/tui/steps/PreviewStep.js +36 -0
- package/dist/src/import/tui/steps/RunningStep.d.ts +10 -0
- package/dist/src/import/tui/steps/RunningStep.js +20 -0
- package/dist/src/import/tui/steps/TokenInputStep.d.ts +8 -0
- package/dist/src/import/tui/steps/TokenInputStep.js +70 -0
- package/dist/src/import/tui/steps/WelcomeStep.d.ts +7 -0
- package/dist/src/import/tui/steps/WelcomeStep.js +33 -0
- package/dist/src/import/tui/steps/WizardPreviewStep.d.ts +15 -0
- package/dist/src/import/tui/steps/WizardPreviewStep.js +121 -0
- package/dist/src/import/tui/steps/preview-diff.d.ts +10 -0
- package/dist/src/import/tui/steps/preview-diff.js +132 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +2 -0
- package/dist/src/output/format.d.ts +23 -0
- package/dist/src/output/format.js +110 -0
- package/dist/src/print/command.d.ts +2 -0
- package/dist/src/print/command.js +199 -0
- package/dist/src/print/validate/tui/ValidateView.d.ts +15 -0
- package/dist/src/print/validate/tui/ValidateView.js +37 -0
- package/dist/src/print/validate/validators/cdf-validator.d.ts +2 -0
- package/dist/src/print/validate/validators/cdf-validator.js +104 -0
- package/dist/src/print/validate/validators/dtcg-validator.d.ts +2 -0
- package/dist/src/print/validate/validators/dtcg-validator.js +110 -0
- package/dist/src/print/validate/validators/format-errors.d.ts +12 -0
- package/dist/src/print/validate/validators/format-errors.js +18 -0
- package/dist/src/program.d.ts +2 -0
- package/dist/src/program.js +25 -0
- package/dist/src/session/command.d.ts +2 -0
- package/dist/src/session/command.js +261 -0
- package/dist/src/session/db.d.ts +111 -0
- package/dist/src/session/db.js +1114 -0
- package/dist/src/session/migration.d.ts +4 -0
- package/dist/src/session/migration.js +117 -0
- package/dist/src/session/session-id.d.ts +1 -0
- package/dist/src/session/session-id.js +212 -0
- package/dist/src/session/stats.d.ts +27 -0
- package/dist/src/session/stats.js +89 -0
- package/dist/src/setup/command.d.ts +2 -0
- package/dist/src/setup/command.js +765 -0
- package/dist/src/types.d.ts +48 -0
- package/dist/src/types.js +1 -0
- package/package.json +55 -0
- package/skills/generate-components.md +361 -0
- package/skills/generate-tokens.md +194 -0
- package/skills/select-components.md +180 -0
package/README.md
ADDED
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
# @contentful/experience-design-system-cli
|
|
2
|
+
|
|
3
|
+
CLI for extracting, reviewing, generating, validating, and pushing Contentful Experience Design System component definitions.
|
|
4
|
+
|
|
5
|
+
## Pipeline Overview
|
|
6
|
+
|
|
7
|
+
The commands form a pipeline. Run them in order, or use `import` to orchestrate the whole thing at once:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
analyze extract → analyze select-agent → generate components → apply push
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`analyze select-agent` uses an AI agent to decide which extracted components belong in Contentful Experience Orchestration. You can substitute it with `analyze select` for manual/pattern-based selection.
|
|
14
|
+
|
|
15
|
+
All intermediate data flows through a local SQLite session database (`~/.contentful/experience-design-system-cli/pipeline.db`). No JSON files are written between steps — each command reads its inputs from the session and writes its outputs back to it. Use `print` to export session data to JSON files on demand (e.g. for inspection or manual validation).
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
|
|
21
|
+
### Coding agent
|
|
22
|
+
|
|
23
|
+
`generate components` (and `generate tokens`) requires a coding agent CLI in your `$PATH`. Choose one:
|
|
24
|
+
|
|
25
|
+
| Agent | Install | Auth |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| **Claude Code** (`claude`) | `npm install -g @anthropic-ai/claude-code` | `claude login` (browser OAuth) **or** set `ANTHROPIC_API_KEY` |
|
|
28
|
+
| **OpenAI Codex** (`codex`) | `npm install -g @openai/codex` | Set `OPENAI_API_KEY` |
|
|
29
|
+
| **OpenCode** (`opencode`) | `npm install -g opencode-ai` | Configure via `opencode auth` (supports multiple providers) |
|
|
30
|
+
| **Cursor** (`cursor`) | Install [Cursor](https://cursor.com) | Sign in to Cursor; exposes `cursor-agent` binary |
|
|
31
|
+
|
|
32
|
+
The CLI invokes the agent non-interactively in a subprocess. If the binary is not found in `$PATH`, the command exits 1 and prints manual fallback instructions.
|
|
33
|
+
|
|
34
|
+
### Contentful credentials
|
|
35
|
+
|
|
36
|
+
`apply preview`, `apply select`, `apply push`, and `import` require access to a Contentful space. Set these environment variables (or pass the equivalent flags):
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
export CONTENTFUL_MANAGEMENT_TOKEN=<your-cma-token> # required
|
|
40
|
+
export CONTENTFUL_SPACE_ID=<your-space-id> # required
|
|
41
|
+
export CONTENTFUL_ENVIRONMENT_ID=master # required
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Option A — Contentful CLI:**
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install -g contentful-cli
|
|
48
|
+
contentful login # opens browser OAuth flow; token is stored in ~/.contentfulrc.json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
After logging in, retrieve the token:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Prints the stored token
|
|
55
|
+
contentful login
|
|
56
|
+
|
|
57
|
+
# Or read it directly
|
|
58
|
+
cat ~/.contentfulrc.json
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Option B — Contentful web app:**
|
|
62
|
+
|
|
63
|
+
Settings → API keys → Content management tokens → Generate personal token.
|
|
64
|
+
|
|
65
|
+
Once you have the token, export it:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
export CONTENTFUL_MANAGEMENT_TOKEN=<your-cma-token>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Alternatively, pass `--cma-token`, `--space-id`, and `--environment-id` directly on each command.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Commands
|
|
76
|
+
|
|
77
|
+
### `analyze extract`
|
|
78
|
+
|
|
79
|
+
Extract component definitions from a project source tree.
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
experience-design-system-cli analyze extract --project <path> [--dir <src-dir>]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
| Option | Default | Description |
|
|
86
|
+
|---|---|---|
|
|
87
|
+
| `--project <path>` | _(required)_ | Path to the project root |
|
|
88
|
+
| `--dir <path>` | `src` (falls back to project root) | Source directory relative to project root |
|
|
89
|
+
|
|
90
|
+
Scans `.tsx`, `.ts`, `.jsx`, `.js`, `.vue`, and `.astro` files. Ignores `node_modules`, `dist`, `build`, `.next`, `.nuxt`, `coverage`, `storybook-static`, and `out` directories. Also ignores `*.stories.*`, `*.story.*`, `*.spec.*`, and `*.test.*` files.
|
|
91
|
+
|
|
92
|
+
Writes extracted components to the session database and prints `session=<id>` to stdout. In an interactive terminal, a scrollable TUI displays the extraction summary (including a warning for any components with 0 props and 0 slots); press `q` or `Enter` to exit.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### `analyze select`
|
|
97
|
+
|
|
98
|
+
Interactively select components for generation and optionally patch their definitions. Alias: `analyze edit`.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
experience-design-system-cli analyze select [--session <id>] [--project-root <path>]
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
| Option | Default | Description |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| `--session <id>` | most recent completed `analyze extract` | Session ID from `analyze extract` |
|
|
107
|
+
| `--project-root <path>` | `cwd` | Project root for resolving component source files |
|
|
108
|
+
| `--select-all` | — | Select all components without launching the TUI |
|
|
109
|
+
| `--select <pattern>` | — | Select components whose name contains pattern (repeatable) |
|
|
110
|
+
| `--deselect <pattern>` | — | Deselect components whose name contains pattern (repeatable) |
|
|
111
|
+
| `--accept-all` | — | Alias for `--select-all` |
|
|
112
|
+
| `--reject <pattern>` | — | Alias for `--deselect <pattern>` (repeatable) |
|
|
113
|
+
| `--patch <path>` | — | Path to a JSON patch file for structured overrides |
|
|
114
|
+
|
|
115
|
+
Without `--select-all`, `--select`, `--deselect`, or `--patch`, launches a full-screen TUI (requires 60+ columns). With any non-interactive flag, exits immediately after applying decisions.
|
|
116
|
+
|
|
117
|
+
#### Keyboard Reference
|
|
118
|
+
|
|
119
|
+
| Key | Action |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `↑` / `k` | Navigate up |
|
|
122
|
+
| `↓` / `j` | Navigate down |
|
|
123
|
+
| `Tab` | Toggle focus between sidebar and main panel |
|
|
124
|
+
| `a` | Accept selected component |
|
|
125
|
+
| `r` | Reject selected component |
|
|
126
|
+
| `e` | Enter edit mode for selected component |
|
|
127
|
+
| `s` | Toggle source code panel (requires 120+ cols) |
|
|
128
|
+
| `A` | Approve all unreviewed components |
|
|
129
|
+
| `F` | Open finalize dialog |
|
|
130
|
+
| `q` | Quit (prompts if unsaved edits) |
|
|
131
|
+
| `?` | Toggle help overlay |
|
|
132
|
+
|
|
133
|
+
**In edit mode:**
|
|
134
|
+
|
|
135
|
+
| Key | Action |
|
|
136
|
+
|---|---|
|
|
137
|
+
| Arrow keys | Move cursor |
|
|
138
|
+
| `Ctrl+S` | Save edits (validates JSON) |
|
|
139
|
+
| `Ctrl+Z` | Undo |
|
|
140
|
+
| `Esc` | Discard changes |
|
|
141
|
+
|
|
142
|
+
#### Patch file format
|
|
143
|
+
|
|
144
|
+
`--patch` accepts a JSON array of operations. Each operation targets a component by name:
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
[
|
|
148
|
+
{ "component": "Button", "status": "accepted" },
|
|
149
|
+
{ "component": "Input", "status": "rejected" },
|
|
150
|
+
{ "component": "Card", "set": { "props[name=variant].type": "string" } }
|
|
151
|
+
]
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`set` paths support dot notation and array item matching with `[name=value]` predicates.
|
|
155
|
+
|
|
156
|
+
#### Session resume
|
|
157
|
+
|
|
158
|
+
The review session is persisted in `~/.contentful/experience-design-system-cli/`. If the TUI is interrupted, re-running with the same `--session` resumes where you left off.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
### `analyze select-agent`
|
|
163
|
+
|
|
164
|
+
Use an AI agent to decide which extracted components belong in Contentful Experience Orchestration as Component Types. Accepts any component that renders visible UI (atoms, molecules, and organisms are all valid) and rejects non-visual infrastructure: React hooks, context providers, A/B testing or variant-routing wrappers, analytics trackers, and security utilities. Runs one agent invocation per component at configurable concurrency, mirroring how `generate components` works.
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
experience-design-system-cli analyze select-agent --agent claude [--session <id>]
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
| Option | Default | Description |
|
|
171
|
+
|---|---|---|
|
|
172
|
+
| `--agent <name>` | _(required)_ | Agent to use: `claude`, `codex`, `opencode`, or `cursor` |
|
|
173
|
+
| `--session <id>` | most recent completed `analyze extract` | Session ID from `analyze extract` |
|
|
174
|
+
| `--project-root <path>` | `cwd` | Project root for resolving component source files |
|
|
175
|
+
| `--model <name>` | agent default | Model to use (defaults to a small/fast model per agent) |
|
|
176
|
+
| `--verbose` | — | Show full agent output including reasoning text |
|
|
177
|
+
| `--dry-run` | — | Print the prompt for the first component without invoking the agent |
|
|
178
|
+
|
|
179
|
+
Results are written to the same session state file used by `analyze select`, so `generate components` will pick up the decisions automatically. If you want to review or override the agent's selections, run `analyze select --session <id>` after `select-agent` completes.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
### `generate components`
|
|
184
|
+
|
|
185
|
+
Invoke a coding agent to generate CDF component definitions from raw analysis output. Results are stored in the session database and passed directly to `apply` commands via `--session`. Use `print components` to export them to a JSON file on demand.
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
experience-design-system-cli generate components --agent claude [--session <id>]
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
| Option | Default | Description |
|
|
192
|
+
|---|---|---|
|
|
193
|
+
| `--agent <name>` | _(required)_ | Agent to use: `claude`, `codex`, `opencode`, or `cursor` |
|
|
194
|
+
| `--session <id>` | most recent completed `analyze extract` | Session ID from `analyze extract` |
|
|
195
|
+
| `--tokens <path>` | — | Path to `tokens.json` for token-linked prop resolution (optional) |
|
|
196
|
+
| `--token-map <path>` | — | Path to `token-name-map.json` sidecar (optional) |
|
|
197
|
+
| `--model <name>` | agent default | Model to use (defaults to a small/fast model per agent) |
|
|
198
|
+
| `--dry-run` | — | Print the prompt without invoking the agent |
|
|
199
|
+
|
|
200
|
+
Raw components are loaded from the session database and embedded directly in the prompt — no intermediate file is read. On success, generated CDF components are written back to the session database and `session=<id>` is printed to stdout.
|
|
201
|
+
|
|
202
|
+
**Autonomous mode** (default): the agent runs non-interactively, prints its result between `<<<EDS_OUTPUT_START>>>` / `<<<EDS_OUTPUT_END>>>` sentinel markers, and the CLI stores the validated CDF in the session database.
|
|
203
|
+
|
|
204
|
+
If the agent binary is not found in `$PATH`, the command exits 1 and prints manual fallback instructions including the skill file path.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
### `generate components edit`
|
|
209
|
+
|
|
210
|
+
Review and correct the output of `generate components` before pushing.
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
experience-design-system-cli generate components edit [--session <id>]
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
| Option | Default | Description |
|
|
217
|
+
|---|---|---|
|
|
218
|
+
| `--session <id>` | most recent active session | Session ID to operate on |
|
|
219
|
+
| `--accept-all` | — | Accept all definitions without launching the TUI |
|
|
220
|
+
| `--reject <pattern>` | — | Reject definitions whose name contains pattern (repeatable) |
|
|
221
|
+
| `--patch <path>` | — | Path to a JSON patch file for structured overrides |
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
### `generate tokens`
|
|
228
|
+
|
|
229
|
+
Invoke a coding agent to generate DTCG design tokens from raw token data. Results are stored in the session database and passed directly to `apply` commands via `--session`. Use `print tokens` to export them to a JSON file on demand.
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
experience-design-system-cli generate tokens --agent claude [--raw-tokens <path>]
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
| Option | Default | Description |
|
|
236
|
+
|---|---|---|
|
|
237
|
+
| `--agent <name>` | _(required)_ | Agent to use: `claude`, `codex`, `opencode`, or `cursor` |
|
|
238
|
+
| `--raw-tokens <path>` | — | Path to raw token input file |
|
|
239
|
+
| `--model <name>` | agent default | Model to use (defaults to a small/fast model per agent) |
|
|
240
|
+
| `--dry-run` | — | Print the prompt without invoking the agent |
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
### `generate tokens edit`
|
|
245
|
+
|
|
246
|
+
Review and correct the output of `generate tokens` before pushing.
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
experience-design-system-cli generate tokens edit [--session <id>]
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Accepts the same flags as `generate components edit`.
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
### `print components`
|
|
257
|
+
|
|
258
|
+
Write generated CDF component definitions from the session database to a JSON file.
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
experience-design-system-cli print components [--session <id>] [--out <path>]
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
| Option | Default | Description |
|
|
265
|
+
|---|---|---|
|
|
266
|
+
| `--session <id>` | most recent completed `generate components` session | Session ID to read from |
|
|
267
|
+
| `--out <path>` | `components.json` | Output file path |
|
|
268
|
+
|
|
269
|
+
Exits 1 if no generated components exist for the session.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
### `print tokens`
|
|
274
|
+
|
|
275
|
+
Write generated DTCG design tokens from the session database to a JSON file.
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
experience-design-system-cli print tokens [--session <id>] [--out <path>]
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
| Option | Default | Description |
|
|
282
|
+
|---|---|---|
|
|
283
|
+
| `--session <id>` | most recent completed `generate tokens` session | Session ID to read from |
|
|
284
|
+
| `--out <path>` | `tokens.json` | Output file path |
|
|
285
|
+
|
|
286
|
+
Reconstructs the full DTCG nested tree (groups + leaf tokens) from the normalized session storage. Exits 1 if no generated tokens exist for the session.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
### `print validate`
|
|
291
|
+
|
|
292
|
+
Validate CDF component definitions and/or DTCG token files against their schemas.
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
experience-design-system-cli print validate [--components <path>] [--tokens <path>]
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
| Option | Description |
|
|
299
|
+
|---|---|
|
|
300
|
+
| `--components <path>` | Path to a CDF component JSON file |
|
|
301
|
+
| `--tokens <path>` | Path to a DTCG token JSON file |
|
|
302
|
+
|
|
303
|
+
At least one flag is required. In an interactive terminal, a scrollable TUI displays validation results. Exit code: `0` if all files are valid, `1` if any errors are found.
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
### `apply preview`
|
|
308
|
+
|
|
309
|
+
Show a read-only diff of what `apply push` would do.
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
experience-design-system-cli apply preview \
|
|
313
|
+
--space-id $CONTENTFUL_SPACE_ID \
|
|
314
|
+
--environment-id master \
|
|
315
|
+
--session <id>
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
At least one of `--session`, `--components`, or `--tokens` is required. `--session` and `--components` are mutually exclusive.
|
|
319
|
+
|
|
320
|
+
| Option | Default | Description |
|
|
321
|
+
|---|---|---|
|
|
322
|
+
| `--session <id>` | — | Session ID from `generate components` (reads components from session DB) |
|
|
323
|
+
| `--components <path>` | — | Path to a CDF `components.json` file (alternative to `--session`) |
|
|
324
|
+
| `--tokens <path>` | — | Path to a DTCG `tokens.json` file |
|
|
325
|
+
| `--space-id <id>` | _(required)_ | Contentful space ID |
|
|
326
|
+
| `--environment-id <id>` | _(required)_ | Contentful environment ID |
|
|
327
|
+
| `--cma-token <token>` | `CONTENTFUL_MANAGEMENT_TOKEN` env | CMA personal access token or app token |
|
|
328
|
+
| `--viewports <path>` | single catch-all viewport | JSON file with a viewport array applied to every imported component type |
|
|
329
|
+
| `--host <url>` | `https://api.contentful.com` | Override API base URL |
|
|
330
|
+
| `--include-unchanged` | — | Include unchanged entities in non-interactive JSON output |
|
|
331
|
+
|
|
332
|
+
In interactive mode, renders a two-level TUI: a summary view listing entities by status (new / changed / unchanged / conflict), with `Enter` to expand into a property-level diff view. In non-interactive mode, writes a structured JSON diff to stdout. Exit code: `0` if the diff is clean, `1` if there are kind conflicts that would block the push.
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
### `apply select`
|
|
337
|
+
|
|
338
|
+
Choose a subset of entities to push. Opens a checkbox TUI after computing the diff, or use non-interactive flags.
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
experience-design-system-cli apply select \
|
|
342
|
+
--space-id $CONTENTFUL_SPACE_ID \
|
|
343
|
+
--environment-id master \
|
|
344
|
+
--session <id>
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Accepts the same flags as `apply preview` (except `--include-unchanged`), plus:
|
|
348
|
+
|
|
349
|
+
| Option | Default | Description |
|
|
350
|
+
|---|---|---|
|
|
351
|
+
| `--select-all` | — | Select all entities without launching TUI |
|
|
352
|
+
| `--select <pattern>` | — | Select entities by ID pattern (repeatable) |
|
|
353
|
+
| `--deselect <pattern>` | — | Deselect entities by ID pattern (repeatable) |
|
|
354
|
+
|
|
355
|
+
**Default TUI selection:** entities with status `new` or `changed` are pre-selected; `unchanged` and `kindConflict` start unchecked.
|
|
356
|
+
|
|
357
|
+
**Keyboard map (TUI):**
|
|
358
|
+
|
|
359
|
+
| Key | Action |
|
|
360
|
+
|---|---|
|
|
361
|
+
| `↑` / `↓` | Move cursor |
|
|
362
|
+
| `Space` | Toggle entity |
|
|
363
|
+
| `A` | Select all |
|
|
364
|
+
| `N` | Deselect all |
|
|
365
|
+
| `I` | Push selected entities |
|
|
366
|
+
| `Q` | Quit without pushing |
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
### `apply push`
|
|
371
|
+
|
|
372
|
+
Write component types and design tokens to Contentful ExO.
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
experience-design-system-cli apply push \
|
|
376
|
+
--space-id $CONTENTFUL_SPACE_ID \
|
|
377
|
+
--environment-id master \
|
|
378
|
+
--session <id>
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
Accepts the same flags as `apply preview` (except `--include-unchanged`), plus:
|
|
382
|
+
|
|
383
|
+
| Option | Default | Description |
|
|
384
|
+
|---|---|---|
|
|
385
|
+
| `--yes` | — | Skip interactive confirmation (required in non-TTY mode) |
|
|
386
|
+
|
|
387
|
+
Design tokens are written first (component types may reference token kinds). Each entity write is recorded in the session database atomically — if the push is interrupted, re-running with the same flags resumes from where it left off, skipping already-succeeded entities.
|
|
388
|
+
|
|
389
|
+
#### Viewport configuration
|
|
390
|
+
|
|
391
|
+
By default every imported component type gets a single catch-all viewport:
|
|
392
|
+
|
|
393
|
+
```json
|
|
394
|
+
[{ "id": "all", "query": "*", "displayName": "All Sizes", "previewSize": "100%" }]
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
To apply a custom set, pass `--viewports <path>` with a JSON array of objects containing `id`, `query`, `displayName`, and `previewSize`.
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
### `import`
|
|
402
|
+
|
|
403
|
+
Run the full pipeline in one command: analyze → select-agent → generate → push.
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
experience-design-system-cli import \
|
|
407
|
+
--space-id $CONTENTFUL_SPACE_ID \
|
|
408
|
+
--environment-id master \
|
|
409
|
+
--cma-token $CONTENTFUL_MANAGEMENT_TOKEN \
|
|
410
|
+
--project <path> \
|
|
411
|
+
--agent claude
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
Contentful credentials (`--space-id`, `--environment-id`, `--cma-token`) are only required when the apply step runs. Pass `--skip-apply` to run the pipeline without pushing to Contentful.
|
|
415
|
+
|
|
416
|
+
The select step uses `analyze select-agent` by default, letting the agent decide which components belong in Experience Orchestration. Pass `--select-all`, `--select`, or `--deselect` to override with pattern-based selection instead. To review and select components interactively, run the steps manually rather than using `import`.
|
|
417
|
+
|
|
418
|
+
| Option | Default | Description |
|
|
419
|
+
|---|---|---|
|
|
420
|
+
| `--space-id <id>` | _(required unless `--skip-apply`)_ | Contentful space ID |
|
|
421
|
+
| `--environment-id <id>` | _(required unless `--skip-apply`)_ | Contentful environment ID |
|
|
422
|
+
| `--cma-token <token>` | `CONTENTFUL_MANAGEMENT_TOKEN` env | CMA personal access token or app token |
|
|
423
|
+
| `--project <path>` | `.` | Path to the project root to analyze |
|
|
424
|
+
| `--out <path>` | `<project>/.contentful` | Directory where `components.json` is written when `--print` is set |
|
|
425
|
+
| `--agent <name>` | `claude` | Agent to use for `analyze select-agent` and `generate components` |
|
|
426
|
+
| `--model <name>` | agent default | Model to use for agent steps |
|
|
427
|
+
| `--select-all` | — | Skip agentic select; accept all extracted components |
|
|
428
|
+
| `--select <pattern>` | — | Skip agentic select; accept components matching pattern (repeatable) |
|
|
429
|
+
| `--deselect <pattern>` | — | Skip agentic select; deselect components matching pattern (repeatable) |
|
|
430
|
+
| `--skip-analyze` | — | Skip analyze; use most recent `analyze extract` session |
|
|
431
|
+
| `--skip-generate` | — | Skip generate; use most recent `generate components` session |
|
|
432
|
+
| `--print` | — | Write `components.json` to `--out` after generation |
|
|
433
|
+
| `--skip-apply` | — | Skip pushing to Contentful (stops after generate) |
|
|
434
|
+
| `--no-cache` | — | Re-run all steps even if output already exists |
|
|
435
|
+
| `--yes` | — | Skip interactive confirmation in `apply push` |
|
|
436
|
+
| `--viewports <path>` | — | JSON file with viewport array (passed to `apply push`) |
|
|
437
|
+
| `--host <url>` | — | Override API base URL (passed to `apply push`) |
|
|
438
|
+
| `--dry-run` | — | Print the generate prompt without invoking the agent |
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
### `session list`
|
|
443
|
+
|
|
444
|
+
List all pipeline sessions.
|
|
445
|
+
|
|
446
|
+
```bash
|
|
447
|
+
experience-design-system-cli session list [--status <status>] [--limit <n>] [--json]
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
| Option | Default | Description |
|
|
451
|
+
|---|---|---|
|
|
452
|
+
| `--status <status>` | — | Filter by `in-progress`, `complete`, `failed`, or `interrupted` |
|
|
453
|
+
| `--all` | — | Include interrupted sessions (hidden by default) |
|
|
454
|
+
| `--limit <n>` | `20` | Max rows to return |
|
|
455
|
+
| `--json` | — | Force JSON output |
|
|
456
|
+
|
|
457
|
+
---
|
|
458
|
+
|
|
459
|
+
### `session show <id>`
|
|
460
|
+
|
|
461
|
+
Show all steps for a session.
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
experience-design-system-cli session show <id> [--json]
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
### `session stats`
|
|
470
|
+
|
|
471
|
+
Show aggregate storage and record counts for the pipeline database.
|
|
472
|
+
|
|
473
|
+
```bash
|
|
474
|
+
experience-design-system-cli session stats [--json]
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
### `session prune`
|
|
480
|
+
|
|
481
|
+
Delete sessions matching criteria.
|
|
482
|
+
|
|
483
|
+
```bash
|
|
484
|
+
experience-design-system-cli session prune --older-than 30d [--dry-run] [--yes]
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
| Option | Description |
|
|
488
|
+
|---|---|
|
|
489
|
+
| `--id <id>` | Delete a specific session by ID |
|
|
490
|
+
| `--older-than <duration>` | Delete sessions older than this age (e.g. `30d`, `2w`, `1y`) |
|
|
491
|
+
| `--status <status>` | Delete sessions by last step status: `complete`, `failed`, `interrupted` |
|
|
492
|
+
| `--yes` | Skip confirmation prompt |
|
|
493
|
+
| `--dry-run` | Print what would be deleted without deleting |
|
|
494
|
+
|
|
495
|
+
At least one of `--id`, `--older-than`, or `--status` is required.
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
## Session Database
|
|
500
|
+
|
|
501
|
+
All pipeline state is stored in `~/.contentful/experience-design-system-cli/pipeline.db` (SQLite). The path can be overridden with the `EDS_PIPELINE_DB_PATH` environment variable.
|
|
502
|
+
|
|
503
|
+
Sessions are created by `analyze extract` and shared across all downstream commands. Use `session list` to see active sessions and `session prune` to clean up old ones.
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## Terminal Compatibility
|
|
508
|
+
|
|
509
|
+
- Minimum 60 columns required for `analyze edit` interactive mode
|
|
510
|
+
- 80+ columns recommended for full sidebar + detail view
|
|
511
|
+
- 120+ columns required to show the source code panel
|
|
512
|
+
- `NO_COLOR=1` suppresses all ANSI color output
|
|
513
|
+
- Windows: supported via Ink v4; known limitations with older ConEmu and cmd.exe
|
|
514
|
+
|
|
515
|
+
---
|
|
516
|
+
|
|
517
|
+
## Development
|
|
518
|
+
|
|
519
|
+
```bash
|
|
520
|
+
# Install dependencies from repo root
|
|
521
|
+
pnpm install
|
|
522
|
+
|
|
523
|
+
# Build
|
|
524
|
+
pnpm -F @contentful/experience-design-system-cli build
|
|
525
|
+
|
|
526
|
+
# Run tests
|
|
527
|
+
pnpm -F @contentful/experience-design-system-cli test
|
|
528
|
+
|
|
529
|
+
# Typecheck
|
|
530
|
+
pnpm -F @contentful/experience-design-system-cli typecheck
|
|
531
|
+
```
|
|
532
|
+
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Suppress the SQLite ExperimentalWarning before any modules load.
|
|
3
|
+
// Must use dynamic import so this handler registers before sqlite is imported.
|
|
4
|
+
process.removeAllListeners("warning");
|
|
5
|
+
process.on("warning", (w) => {
|
|
6
|
+
if (w.name === "ExperimentalWarning" && w.message.includes("SQLite")) return;
|
|
7
|
+
process.stderr.write(`${w.name}: ${w.message}\n`);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
// Auto-rebuild when running from source (dev mode only).
|
|
11
|
+
// Skipped when src/ doesn't exist (e.g. npm-installed users).
|
|
12
|
+
import { existsSync, statSync, readdirSync } from "node:fs";
|
|
13
|
+
import { execFileSync } from "node:child_process";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
import { dirname, resolve, join } from "node:path";
|
|
16
|
+
|
|
17
|
+
function newestMtime(dir, depth = 0) {
|
|
18
|
+
if (depth > 10) return 0;
|
|
19
|
+
let max = 0;
|
|
20
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
21
|
+
if (entry.isSymbolicLink()) continue;
|
|
22
|
+
const full = join(dir, entry.name);
|
|
23
|
+
if (entry.isDirectory()) {
|
|
24
|
+
max = Math.max(max, newestMtime(full, depth + 1));
|
|
25
|
+
} else if (entry.name.endsWith(".ts") || entry.name.endsWith(".tsx")) {
|
|
26
|
+
max = Math.max(max, statSync(full).mtimeMs);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return max;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
33
|
+
const pkgRoot = resolve(__dirname, "..");
|
|
34
|
+
const srcDir = join(pkgRoot, "src");
|
|
35
|
+
const distEntry = join(pkgRoot, "dist", "src", "index.js");
|
|
36
|
+
|
|
37
|
+
if (
|
|
38
|
+
existsSync(srcDir) &&
|
|
39
|
+
existsSync(distEntry) &&
|
|
40
|
+
process.env.NODE_ENV !== "test"
|
|
41
|
+
) {
|
|
42
|
+
const distMtime = statSync(distEntry).mtimeMs;
|
|
43
|
+
if (newestMtime(srcDir) > distMtime) {
|
|
44
|
+
process.stderr.write("⚙ Source changed — rebuilding...\n");
|
|
45
|
+
const tsc = join(pkgRoot, "node_modules", ".bin", "tsc");
|
|
46
|
+
try {
|
|
47
|
+
execFileSync(tsc, ["-p", join(pkgRoot, "tsconfig.build.json")], {
|
|
48
|
+
stdio: ["ignore", "ignore", "inherit"],
|
|
49
|
+
cwd: pkgRoot,
|
|
50
|
+
});
|
|
51
|
+
process.stderr.write("✓ Build complete\n");
|
|
52
|
+
} catch {
|
|
53
|
+
process.stderr.write("✗ Build failed — running with existing dist\n");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
await import("../dist/src/index.js");
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@contentful/experience-design-system-cli",
|
|
3
|
+
"version": "2.2.1",
|
|
4
|
+
"description": "Contentful Experiences design system import CLI",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"experience-design-system-cli": "./bin/cli.js",
|
|
8
|
+
"exo": "./bin/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/src/index.js",
|
|
11
|
+
"types": "./dist/src/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/src/index.d.ts",
|
|
15
|
+
"import": "./dist/src/index.js",
|
|
16
|
+
"node": "./dist/src/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"bin/",
|
|
21
|
+
"dist/",
|
|
22
|
+
"skills/"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "nx build experience-design-system-cli",
|
|
26
|
+
"typecheck": "nx typecheck experience-design-system-cli",
|
|
27
|
+
"clean": "nx clean experience-design-system-cli",
|
|
28
|
+
"test": "nx test experience-design-system-cli",
|
|
29
|
+
"test:watch": "nx test:watch experience-design-system-cli",
|
|
30
|
+
"lint": "nx lint experience-design-system-cli",
|
|
31
|
+
"lint:fix": "nx lint:fix experience-design-system-cli"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@contentful/experience-design-system-types": "workspace:*",
|
|
35
|
+
"@vue/compiler-sfc": "^3.5.31",
|
|
36
|
+
"commander": "^13.1.0",
|
|
37
|
+
"ink": "^4.4.1",
|
|
38
|
+
"react": "^18.3.1",
|
|
39
|
+
"react-devtools-core": "^4.19.1",
|
|
40
|
+
"react-dom": "^18.3.1",
|
|
41
|
+
"ts-morph": "^27.0.2",
|
|
42
|
+
"typescript": "^5.9.3"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@tsconfig/node24": "^24.0.3",
|
|
46
|
+
"@types/node": "^24.0.3",
|
|
47
|
+
"@types/react": "^18.3.24",
|
|
48
|
+
"eslint": "^9.39.2",
|
|
49
|
+
"eslint-config-prettier": "^10.1.8",
|
|
50
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
51
|
+
"ink-testing-library": "^4.0.0",
|
|
52
|
+
"typescript-eslint": "^8.52.0",
|
|
53
|
+
"vitest": "^4.0.16"
|
|
54
|
+
},
|
|
55
|
+
"module": "./src/index.js"
|
|
56
|
+
}
|