@actuate-media/cli 0.8.0 → 0.11.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.
@@ -1,4 +1,4 @@
1
1
 
2
- > @actuate-media/cli@0.8.0 build /home/runner/work/actuatecms/actuatecms/packages/cli
2
+ > @actuate-media/cli@0.11.0 build /home/runner/work/actuatecms/actuatecms/packages/cli
3
3
  > tsc
4
4
 
@@ -1,26 +1,28 @@
1
1
 
2
- > @actuate-media/cli@0.8.0 test /home/runner/work/actuatecms/actuatecms/packages/cli
2
+ > @actuate-media/cli@0.11.0 test /home/runner/work/actuatecms/actuatecms/packages/cli
3
3
  > vitest run
4
4
 
5
5
 
6
6
   RUN  v4.1.8 /home/runner/work/actuatecms/actuatecms/packages/cli
7
7
 
8
- ✓ dist/__tests__/db-sync.test.js (10 tests) 667ms
9
- ✓ src/__tests__/db-sync.test.ts (10 tests) 416ms
10
- ✓ dist/__tests__/deployment-diagnostics.test.js (8 tests) 84ms
11
- ✓ src/__tests__/deployment-diagnostics.test.ts (8 tests) 80ms
8
+ ✓ dist/__tests__/db-sync.test.js (10 tests) 462ms
9
+ ✓ dist/__tests__/seed.test.js (10 tests) 201ms
10
+ ✓ src/__tests__/db-sync.test.ts (10 tests) 468ms
11
+ ✓ src/__tests__/seed.test.ts (10 tests) 194ms
12
+ ✓ dist/__tests__/deployment-diagnostics.test.js (8 tests) 52ms
13
+ ✓ src/__tests__/deployment-diagnostics.test.ts (8 tests) 59ms
12
14
  - Reading canonical Actuate schema...
15
+ ✔ Actuate CMS models added to schema.
16
+ - Running prisma generate...
13
17
  stdout | dist/__tests__/db-init.test.js > db:init (WS-D D5 — canonical schema, no stale fragment) > command > injects canonical models with @@map and no duplicate datasource/generator
14
18
  ✔ Prisma client generated.
15
19
  ℹ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
16
20
 
17
- ✔ Actuate CMS models added to schema.
18
- - Running prisma generate...
21
+ - Reading canonical Actuate schema...
22
+ ✖ Could not locate @actuate-media/cms-core.
19
23
  stdout | dist/__tests__/db-init.test.js > db:init (WS-D D5 — canonical schema, no stale fragment) > command > fails clearly when cms-core cannot be located
20
24
  ℹ Install it first: `npm install @actuate-media/cms-core`.
21
25
 
22
- - Reading canonical Actuate schema...
23
- ✖ Could not locate @actuate-media/cms-core.
24
26
  - Reading canonical Actuate schema...
25
27
  ✔ Actuate CMS models added to schema.
26
28
  - Running prisma generate...
@@ -30,41 +32,299 @@
30
32
 
31
33
  - Reading canonical Actuate schema...
32
34
  ℹ Actuate CMS models already present in schema. Use --force to overwrite.
33
- ✓ dist/__tests__/db-init.test.js (4 tests) 324ms
35
+ ✓ dist/__tests__/db-init.test.js (4 tests) 365ms
34
36
  - Reading canonical Actuate schema...
35
37
  ✔ Actuate CMS models added to schema.
38
+ - Running prisma generate...
36
39
  stdout | src/__tests__/db-init.test.ts > db:init (WS-D D5 — canonical schema, no stale fragment) > command > injects canonical models with @@map and no duplicate datasource/generator
37
40
  ✔ Prisma client generated.
38
- - Running prisma generate...
39
41
  ℹ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
40
42
 
41
43
  stdout | src/__tests__/db-init.test.ts > db:init (WS-D D5 — canonical schema, no stale fragment) > command > fails clearly when cms-core cannot be located
42
44
  ℹ Install it first: `npm install @actuate-media/cms-core`.
43
-
44
45
  - Reading canonical Actuate schema...
46
+
45
47
  ✖ Could not locate @actuate-media/cms-core.
46
48
  - Reading canonical Actuate schema...
49
+ ✔ Actuate CMS models added to schema.
50
+ - Running prisma generate...
47
51
  stdout | src/__tests__/db-init.test.ts > db:init (WS-D D5 — canonical schema, no stale fragment) > command > is idempotent without --force
48
52
  ✔ Prisma client generated.
49
- ✔ Actuate CMS models added to schema.
50
53
  ℹ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
51
54
 
52
- - Running prisma generate...
53
55
  - Reading canonical Actuate schema...
54
56
  ℹ Actuate CMS models already present in schema. Use --force to overwrite.
55
- ✓ src/__tests__/db-init.test.ts (4 tests) 381ms
56
- ✓ dist/__tests__/seed.test.js (5 tests) 85ms
57
- ✓ src/__tests__/seed.test.ts (5 tests) 52ms
58
- ✓ dist/__tests__/vercel-env-matrix.test.js (5 tests) 40ms
59
- ✓ src/__tests__/vercel-env-matrix.test.ts (5 tests) 63ms
57
+ ✓ src/__tests__/db-init.test.ts (4 tests) 391ms
58
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > creates both editor configs with placeholder key and git-ignores them
59
+ ✔ Created .cursor/mcp.json
60
+
61
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > creates both editor configs with placeholder key and git-ignores them
62
+ ✔ Created .vscode/mcp.json
63
+
64
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > creates both editor configs with placeholder key and git-ignores them
65
+ ✔ Added to .gitignore: .cursor/mcp.json, .vscode/mcp.json
66
+
67
+ Next steps
68
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
69
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
70
+ 3. Restart Cursor / VS Code so the MCP server is picked up
71
+ Tip: pass --url https://your-site.com to target a deployed CMS instead.
72
+
73
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > applies --url and --key to both configs
74
+ ✔ Created .cursor/mcp.json
75
+
76
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > applies --url and --key to both configs
77
+ ✔ Created .vscode/mcp.json
78
+
79
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > applies --url and --key to both configs
80
+ ✔ Added to .gitignore: .cursor/mcp.json, .vscode/mcp.json
81
+
82
+ Next steps
83
+ 1. Restart Cursor / VS Code so the MCP server is picked up
84
+
85
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > merges into an existing config without clobbering other servers
86
+ ✔ Updated .cursor/mcp.json
87
+
88
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > merges into an existing config without clobbering other servers
89
+ ✔ Created .vscode/mcp.json
90
+
91
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > merges into an existing config without clobbering other servers
92
+ ✔ Added to .gitignore: .cursor/mcp.json, .vscode/mcp.json
93
+
94
+ Next steps
95
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
96
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
97
+ 3. Restart Cursor / VS Code so the MCP server is picked up
98
+ Tip: pass --url https://your-site.com to target a deployed CMS instead.
99
+
100
+ stderr | dist/__tests__/mcp-init.test.js > mcp:init > leaves an existing actuate entry alone unless --force is passed
101
+ ⚠ .cursor/mcp.json already has an "actuate" server — use --force to replace it.
102
+
103
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > leaves an existing actuate entry alone unless --force is passed
104
+ ✔ Created .vscode/mcp.json
105
+
106
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > leaves an existing actuate entry alone unless --force is passed
107
+ ✔ Added to .gitignore: .cursor/mcp.json, .vscode/mcp.json
108
+
109
+ Next steps
110
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
111
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
112
+ 3. Restart Cursor / VS Code so the MCP server is picked up
113
+ Tip: pass --url https://your-site.com to target a deployed CMS instead.
114
+
115
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > leaves an existing actuate entry alone unless --force is passed
116
+ ✔ Updated .cursor/mcp.json
117
+
118
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > leaves an existing actuate entry alone unless --force is passed
119
+ ✔ Updated .vscode/mcp.json
120
+
121
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > leaves an existing actuate entry alone unless --force is passed
122
+ 
123
+ Next steps
124
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
125
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
126
+ 3. Restart Cursor / VS Code so the MCP server is picked up
127
+
128
+ stderr | dist/__tests__/mcp-init.test.js > mcp:init > fails on invalid JSON without --force, overwrites with --force
129
+ ✖ .cursor/mcp.json contains invalid JSON — fix it or re-run with --force.
130
+
131
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > fails on invalid JSON without --force, overwrites with --force
132
+ ✔ Created .vscode/mcp.json
133
+
134
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > fails on invalid JSON without --force, overwrites with --force
135
+ ✔ Added to .gitignore: .cursor/mcp.json, .vscode/mcp.json
136
+
137
+ Next steps
138
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
139
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
140
+ 3. Restart Cursor / VS Code so the MCP server is picked up
141
+ Tip: pass --url https://your-site.com to target a deployed CMS instead.
142
+
143
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > fails on invalid JSON without --force, overwrites with --force
144
+ ✔ Updated .cursor/mcp.json
145
+
146
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > fails on invalid JSON without --force, overwrites with --force
147
+ ✔ Updated .vscode/mcp.json
148
+
149
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > fails on invalid JSON without --force, overwrites with --force
150
+ 
151
+ Next steps
152
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
153
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
154
+ 3. Restart Cursor / VS Code so the MCP server is picked up
155
+ Tip: pass --url https://your-site.com to target a deployed CMS instead.
156
+
157
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > does not duplicate gitignore entries on re-runs
158
+ ✔ Created .cursor/mcp.json
159
+
160
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > does not duplicate gitignore entries on re-runs
161
+ ✔ Created .vscode/mcp.json
162
+
163
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > does not duplicate gitignore entries on re-runs
164
+ ✔ Added to .gitignore: .cursor/mcp.json, .vscode/mcp.json
165
+
166
+ Next steps
167
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
168
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
169
+ 3. Restart Cursor / VS Code so the MCP server is picked up
170
+ Tip: pass --url https://your-site.com to target a deployed CMS instead.
171
+
172
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > does not duplicate gitignore entries on re-runs
173
+ ✔ Updated .cursor/mcp.json
174
+
175
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > does not duplicate gitignore entries on re-runs
176
+ ✔ Updated .vscode/mcp.json
177
+
178
+ stdout | dist/__tests__/mcp-init.test.js > mcp:init > does not duplicate gitignore entries on re-runs
179
+ 
180
+ Next steps
181
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
182
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
183
+ 3. Restart Cursor / VS Code so the MCP server is picked up
184
+ Tip: pass --url https://your-site.com to target a deployed CMS instead.
185
+
186
+ ✓ dist/__tests__/mcp-init.test.js (6 tests) 514ms
187
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > creates both editor configs with placeholder key and git-ignores them
188
+ ✔ Created .cursor/mcp.json
189
+
190
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > creates both editor configs with placeholder key and git-ignores them
191
+ ✔ Created .vscode/mcp.json
192
+
193
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > creates both editor configs with placeholder key and git-ignores them
194
+ ✔ Added to .gitignore: .cursor/mcp.json, .vscode/mcp.json
195
+
196
+ Next steps
197
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
198
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
199
+ 3. Restart Cursor / VS Code so the MCP server is picked up
200
+ Tip: pass --url https://your-site.com to target a deployed CMS instead.
201
+
202
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > applies --url and --key to both configs
203
+ ✔ Created .cursor/mcp.json
204
+
205
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > applies --url and --key to both configs
206
+ ✔ Created .vscode/mcp.json
207
+
208
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > applies --url and --key to both configs
209
+ ✔ Added to .gitignore: .cursor/mcp.json, .vscode/mcp.json
210
+
211
+ Next steps
212
+ 1. Restart Cursor / VS Code so the MCP server is picked up
213
+
214
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > merges into an existing config without clobbering other servers
215
+ ✔ Updated .cursor/mcp.json
216
+
217
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > merges into an existing config without clobbering other servers
218
+ ✔ Created .vscode/mcp.json
219
+
220
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > merges into an existing config without clobbering other servers
221
+ ✔ Added to .gitignore: .cursor/mcp.json, .vscode/mcp.json
222
+
223
+ Next steps
224
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
225
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
226
+ 3. Restart Cursor / VS Code so the MCP server is picked up
227
+ Tip: pass --url https://your-site.com to target a deployed CMS instead.
228
+
229
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > leaves an existing actuate entry alone unless --force is passed
230
+ ✔ Created .vscode/mcp.json
231
+
232
+ stderr | src/__tests__/mcp-init.test.ts > mcp:init > leaves an existing actuate entry alone unless --force is passed
233
+ ⚠ .cursor/mcp.json already has an "actuate" server — use --force to replace it.
234
+
235
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > leaves an existing actuate entry alone unless --force is passed
236
+ ✔ Added to .gitignore: .cursor/mcp.json, .vscode/mcp.json
237
+
238
+ Next steps
239
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
240
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
241
+ 3. Restart Cursor / VS Code so the MCP server is picked up
242
+ Tip: pass --url https://your-site.com to target a deployed CMS instead.
243
+
244
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > leaves an existing actuate entry alone unless --force is passed
245
+ ✔ Updated .cursor/mcp.json
246
+
247
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > leaves an existing actuate entry alone unless --force is passed
248
+ ✔ Updated .vscode/mcp.json
249
+
250
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > leaves an existing actuate entry alone unless --force is passed
251
+ 
252
+ Next steps
253
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
254
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
255
+ 3. Restart Cursor / VS Code so the MCP server is picked up
256
+
257
+ stderr | src/__tests__/mcp-init.test.ts > mcp:init > fails on invalid JSON without --force, overwrites with --force
258
+ ✖ .cursor/mcp.json contains invalid JSON — fix it or re-run with --force.
259
+
260
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > fails on invalid JSON without --force, overwrites with --force
261
+ ✔ Created .vscode/mcp.json
262
+
263
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > fails on invalid JSON without --force, overwrites with --force
264
+ ✔ Added to .gitignore: .cursor/mcp.json, .vscode/mcp.json
265
+
266
+ Next steps
267
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
268
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
269
+ 3. Restart Cursor / VS Code so the MCP server is picked up
270
+ Tip: pass --url https://your-site.com to target a deployed CMS instead.
271
+
272
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > fails on invalid JSON without --force, overwrites with --force
273
+ ✔ Updated .cursor/mcp.json
274
+
275
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > fails on invalid JSON without --force, overwrites with --force
276
+ ✔ Updated .vscode/mcp.json
277
+
278
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > fails on invalid JSON without --force, overwrites with --force
279
+ 
280
+ Next steps
281
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
282
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
283
+ 3. Restart Cursor / VS Code so the MCP server is picked up
284
+ Tip: pass --url https://your-site.com to target a deployed CMS instead.
285
+
286
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > does not duplicate gitignore entries on re-runs
287
+ ✔ Created .cursor/mcp.json
288
+
289
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > does not duplicate gitignore entries on re-runs
290
+ ✔ Created .vscode/mcp.json
291
+
292
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > does not duplicate gitignore entries on re-runs
293
+ ✔ Added to .gitignore: .cursor/mcp.json, .vscode/mcp.json
294
+
295
+ Next steps
296
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
297
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
298
+ 3. Restart Cursor / VS Code so the MCP server is picked up
299
+ Tip: pass --url https://your-site.com to target a deployed CMS instead.
300
+
301
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > does not duplicate gitignore entries on re-runs
302
+ ✔ Updated .cursor/mcp.json
303
+
304
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > does not duplicate gitignore entries on re-runs
305
+ ✔ Updated .vscode/mcp.json
306
+
307
+ stdout | src/__tests__/mcp-init.test.ts > mcp:init > does not duplicate gitignore entries on re-runs
308
+ 
309
+ Next steps
310
+ 1. Mint an API key in Admin → Settings → API Keys (act_sk_...)
311
+ 2. Replace act_sk_REPLACE_WITH_YOUR_KEY in both config files with the real key
312
+ 3. Restart Cursor / VS Code so the MCP server is picked up
313
+ Tip: pass --url https://your-site.com to target a deployed CMS instead.
314
+
315
+ ✓ src/__tests__/mcp-init.test.ts (6 tests) 366ms
316
+ ✓ dist/__tests__/form-seed.test.js (10 tests) 67ms
317
+ ✓ src/__tests__/form-seed.test.ts (10 tests) 61ms
318
+ ✓ dist/__tests__/vercel-env-matrix.test.js (5 tests) 49ms
319
+ ✓ src/__tests__/vercel-env-matrix.test.ts (5 tests) 69ms
60
320
  - Reading canonical Actuate schema...
61
321
  ✔ Actuate CMS models added to schema.
62
- - Running prisma generate...
63
322
  stdout | dist/__tests__/schema-fragment.test.js > db:init schema fragment > injects all deploy-critical Actuate models
64
323
  ✔ Prisma client generated.
65
324
  ℹ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
66
325
 
67
- ✓ dist/__tests__/schema-fragment.test.js (1 test) 172ms
326
+ - Running prisma generate...
327
+ ✓ dist/__tests__/schema-fragment.test.js (1 test) 193ms
68
328
  - Reading canonical Actuate schema...
69
329
  ✔ Actuate CMS models added to schema.
70
330
  - Running prisma generate...
@@ -72,12 +332,12 @@
72
332
  ✔ Prisma client generated.
73
333
  ℹ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
74
334
 
75
- ✓ src/__tests__/schema-fragment.test.ts (1 test) 150ms
76
- ✓ dist/__tests__/init.test.js (2 tests) 46ms
77
- ✓ src/__tests__/init.test.ts (2 tests) 52ms
335
+ ✓ src/__tests__/schema-fragment.test.ts (1 test) 172ms
336
+ ✓ dist/__tests__/init.test.js (2 tests) 45ms
337
+ ✓ src/__tests__/init.test.ts (2 tests) 42ms
78
338
 
79
-  Test Files  14 passed (14)
80
-  Tests  70 passed (70)
81
-  Start at  16:12:59
82
-  Duration  20.13s (transform 1.93s, setup 0ms, import 5.06s, tests 2.61s, environment 3ms)
339
+  Test Files  18 passed (18)
340
+  Tests  112 passed (112)
341
+  Start at  03:11:38
342
+  Duration  30.42s (transform 2.66s, setup 0ms, import 7.77s, tests 3.77s, environment 12ms)
83
343
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @actuate-media/cli
2
2
 
3
+ ## 0.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - eb998e5: New `actuate mcp:init` command — retrofit the Actuate MCP server onto existing projects.
8
+
9
+ Writes `.cursor/mcp.json` (Cursor / Claude Desktop shape) and `.vscode/mcp.json` (VS Code shape) wiring `@actuate-media/mcp-server`, with `--url` / `--key` options. Merges into existing configs without clobbering other MCP servers; an existing `actuate` entry is only replaced with `--force`. Both paths are appended to `.gitignore` so a real `act_sk_...` key is never committed. New scaffolds already get these files from `create-actuate-cms` — this closes the gap for projects created before that.
10
+
11
+ ## 0.10.0
12
+
13
+ ### Minor Changes
14
+
15
+ - 232e251: New `actuate seed --upsert` (also on `populate`): documents are matched by collection + slug and updated in place instead of inserting duplicates, making seed files safe to re-run as content evolves. Every update records a version snapshot; `publishedAt` is only stamped on the transition into PUBLISHED; documents without a slug always insert. The summary line reports created vs updated counts.
16
+
17
+ ## 0.9.0
18
+
19
+ ### Minor Changes
20
+
21
+ - be9b5ff: `actuate seed` now validates `forms`-collection entries before writing anything, with actionable per-form errors. The most common mistake — putting the document envelope status (`PUBLISHED`) in `data.status` instead of the form's own lifecycle status (`active` / `draft` / `archived`, which gates the public endpoints) — gets a targeted explanation, as do fields using `name` instead of `key`/`label` and unknown field types. The `--demo` forms were rewritten to the canonical shape (they previously seeded fields without `key`/`label` and no `data.status`, so `/api/cms/public/forms/:slug` 404'd on them).
22
+
23
+ ### Patch Changes
24
+
25
+ - 854152d: Developer experience improvements from external-consumer feedback:
26
+ - Every published package now ships its `CHANGELOG.md` in the npm tarball, and packages that were missing a `README.md` (cli, cms-admin, cms-core, import, platform-vercel, all plugins, sections-react) now have one — so release notes and usage docs are visible on npmjs.com and in `node_modules`.
27
+ - New client-safe form validation entry point: `@actuate-media/cms-core/forms/client` exports `validateFormFieldClient()`, `validateFormValuesClient()`, visibility/conditional helpers, and the exact `FORM_EMAIL_RE` / `FORM_PHONE_RE` regexes the server enforces — zero Node dependencies, so public-site forms can mirror server rules without reimplementing them. The server validator now imports the same primitives, so client and server can never drift.
28
+
3
29
  ## 0.8.0
4
30
 
5
31
  ### Minor Changes
package/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # @actuate-media/cli
2
+
3
+ CLI for [Actuate CMS](https://github.com/actuate-media/actuatecms) —
4
+ migrations, codegen, seeding, imports/exports, verification, and upgrades.
5
+
6
+ ```bash
7
+ npm install -D @actuate-media/cli
8
+ ```
9
+
10
+ ## Common commands
11
+
12
+ ```bash
13
+ actuate migrate # apply Prisma migrations
14
+ actuate seed # seed content from seed scripts
15
+ actuate codegen # generate typed client from actuate.config.ts
16
+ actuate verify # check config, sections, and environment
17
+ actuate verify:cms-sections # editor ↔ frontend section contract check
18
+ actuate update # check for / apply CMS package updates
19
+ ```
20
+
21
+ Run `actuate --help` for the full command list.
22
+
23
+ ## Release notes
24
+
25
+ See [CHANGELOG.md](./CHANGELOG.md) (shipped with the package) or the
26
+ [GitHub releases](https://github.com/actuate-media/actuatecms/releases).
27
+
28
+ ## License
29
+
30
+ MIT
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=form-seed.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-seed.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/form-seed.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,79 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ // seed.js transitively imports cms-core helpers at module scope via mocks
3
+ // elsewhere; keep the same stub so importing DEMO_FORMS stays side-effect-free.
4
+ vi.mock('@actuate-media/cms-core', () => ({
5
+ extractPlainText: vi.fn(),
6
+ hashContent: vi.fn(),
7
+ sanitizeHtml: vi.fn(),
8
+ createInitialAdmin: vi.fn(),
9
+ }));
10
+ import { validateFormSeedData, validateFormSeeds } from '../utils/form-seed.js';
11
+ import { DEMO_FORMS } from '../commands/seed.js';
12
+ const validForm = () => ({
13
+ name: 'Contact',
14
+ slug: 'contact',
15
+ status: 'active',
16
+ fields: [{ id: 'f1', key: 'email', label: 'Email', type: 'email', required: true, sortOrder: 0 }],
17
+ });
18
+ describe('validateFormSeedData', () => {
19
+ it('accepts the canonical form shape', () => {
20
+ expect(validateFormSeedData(validForm())).toEqual([]);
21
+ });
22
+ it('every DEMO_FORMS entry passes its own validation', () => {
23
+ for (const form of DEMO_FORMS) {
24
+ expect(validateFormSeedData(form, form.slug)).toEqual([]);
25
+ }
26
+ });
27
+ it('explains the data.status vs document status split when status is missing', () => {
28
+ const { status: _status, ...form } = validForm();
29
+ const errors = validateFormSeedData(form);
30
+ expect(errors).toHaveLength(1);
31
+ expect(errors[0]).toContain('data.status to "active"');
32
+ expect(errors[0]).toContain('document envelope status');
33
+ });
34
+ it('catches a document-envelope status (PUBLISHED) used as the form status', () => {
35
+ const errors = validateFormSeedData({ ...validForm(), status: 'PUBLISHED' });
36
+ expect(errors).toHaveLength(1);
37
+ expect(errors[0]).toContain('looks like a document envelope status');
38
+ expect(errors[0]).toContain('"active" | "draft" | "archived"');
39
+ });
40
+ it('rejects unknown statuses with the allowed list', () => {
41
+ const errors = validateFormSeedData({ ...validForm(), status: 'live' });
42
+ expect(errors[0]).toContain('invalid data.status "live"');
43
+ });
44
+ it('requires slug, name, and a non-empty fields array', () => {
45
+ const errors = validateFormSeedData({ status: 'active' });
46
+ expect(errors.some((e) => e.includes('"slug"'))).toBe(true);
47
+ expect(errors.some((e) => e.includes('"name"'))).toBe(true);
48
+ expect(errors.some((e) => e.includes('"fields"'))).toBe(true);
49
+ });
50
+ it('points "name"-keyed fields (the old demo shape) at key/label', () => {
51
+ const errors = validateFormSeedData({
52
+ ...validForm(),
53
+ fields: [{ name: 'email', type: 'email' }],
54
+ });
55
+ expect(errors.some((e) => e.includes('Rename name → key'))).toBe(true);
56
+ expect(errors.some((e) => e.includes('"label"'))).toBe(true);
57
+ });
58
+ it('rejects unknown field types', () => {
59
+ const errors = validateFormSeedData({
60
+ ...validForm(),
61
+ fields: [{ key: 'x', label: 'X', type: 'dropdown' }],
62
+ });
63
+ expect(errors[0]).toContain('invalid type "dropdown"');
64
+ });
65
+ });
66
+ describe('validateFormSeeds', () => {
67
+ it('only validates forms-collection documents and labels errors by slug', () => {
68
+ const errors = validateFormSeeds([
69
+ { collection: 'pages', data: { title: 'Home' } },
70
+ { collection: 'forms', data: { ...validForm(), slug: 'contact', status: 'PUBLISHED' } },
71
+ ]);
72
+ expect(errors).toHaveLength(1);
73
+ expect(errors[0]).toContain('forms "contact"');
74
+ });
75
+ it('returns no errors for a payload without forms', () => {
76
+ expect(validateFormSeeds([{ collection: 'pages', data: {} }])).toEqual([]);
77
+ });
78
+ });
79
+ //# sourceMappingURL=form-seed.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-seed.test.js","sourceRoot":"","sources":["../../src/__tests__/form-seed.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mcp-init.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-init.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/mcp-init.test.ts"],"names":[],"mappings":""}