@memberjunction/cli 6.1.0-edge.5 → 6.1.0-edge.7

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 (36) hide show
  1. package/README.md +23 -0
  2. package/dist/commands/dev/workspace/index.d.ts +9 -0
  3. package/dist/commands/dev/workspace/index.d.ts.map +1 -1
  4. package/dist/commands/dev/workspace/index.js +82 -6
  5. package/dist/commands/dev/workspace/index.js.map +1 -1
  6. package/dist/config.d.ts +127 -2
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +24 -2
  9. package/dist/config.js.map +1 -1
  10. package/dist/hooks/prerun.d.ts +6 -0
  11. package/dist/hooks/prerun.d.ts.map +1 -1
  12. package/dist/hooks/prerun.js +29 -3
  13. package/dist/hooks/prerun.js.map +1 -1
  14. package/dist/lib/dev-workspace/build.d.ts +155 -18
  15. package/dist/lib/dev-workspace/build.d.ts.map +1 -1
  16. package/dist/lib/dev-workspace/build.js +522 -39
  17. package/dist/lib/dev-workspace/build.js.map +1 -1
  18. package/dist/lib/dev-workspace/detect.d.ts +14 -1
  19. package/dist/lib/dev-workspace/detect.d.ts.map +1 -1
  20. package/dist/lib/dev-workspace/detect.js +60 -3
  21. package/dist/lib/dev-workspace/detect.js.map +1 -1
  22. package/dist/lib/dev-workspace/doctor.d.ts +17 -1
  23. package/dist/lib/dev-workspace/doctor.d.ts.map +1 -1
  24. package/dist/lib/dev-workspace/doctor.js +92 -1
  25. package/dist/lib/dev-workspace/doctor.js.map +1 -1
  26. package/dist/lib/dev-workspace/types.d.ts +185 -2
  27. package/dist/lib/dev-workspace/types.d.ts.map +1 -1
  28. package/dist/lib/dev-workspace/usage.d.ts.map +1 -1
  29. package/dist/lib/dev-workspace/usage.js +5 -3
  30. package/dist/lib/dev-workspace/usage.js.map +1 -1
  31. package/dist/lib/dynamic-packages.d.ts +31 -0
  32. package/dist/lib/dynamic-packages.d.ts.map +1 -0
  33. package/dist/lib/dynamic-packages.js +56 -0
  34. package/dist/lib/dynamic-packages.js.map +1 -0
  35. package/oclif.manifest.json +1802 -1742
  36. package/package.json +22 -21
@@ -93,77 +93,54 @@
93
93
  "usage.js"
94
94
  ]
95
95
  },
96
- "app:check-updates": {
96
+ "artifacts:reclassify": {
97
97
  "aliases": [],
98
98
  "args": {},
99
- "description": "Check for available upgrades for installed MJ Open Apps",
100
- "examples": [
101
- "<%= config.bin %> app check-updates"
102
- ],
103
- "flags": {},
104
- "hasDynamicHelp": false,
105
- "hiddenAliases": [],
106
- "id": "app:check-updates",
107
- "pluginAlias": "@memberjunction/cli",
108
- "pluginName": "@memberjunction/cli",
109
- "pluginType": "core",
110
- "strict": true,
111
- "enableJsonFlag": false,
112
- "isESM": true,
113
- "relativePath": [
114
- "dist",
115
- "commands",
116
- "app",
117
- "check-updates.js"
118
- ]
119
- },
120
- "app:disable": {
121
- "aliases": [],
122
- "args": {
123
- "name": {
124
- "description": "Name of the installed app to disable",
125
- "name": "name",
126
- "required": true
127
- }
128
- },
129
- "description": "Disable an installed MJ Open App without removing it",
99
+ "description": "Upgrade-recovery utility for v5.35 artifact unification. Re-evaluates rows whose TypeID is the deleted JSON fallback but whose actual content does not parse as JSON. Normally a no-op: the v5.35 backfill migration handles this automatically. This command is only relevant when the migration ran BEFORE the artifact-type metadata (Generic Text / Generic Binary) was pushed via `mj sync push`, in which case the migration prints a notice telling you to run this. Reports \"no candidates\" once everything is reconciled. Dry-run by default; --apply writes through Record Changes.",
130
100
  "examples": [
131
- "<%= config.bin %> app disable acme-crm"
101
+ "<%= config.bin %> <%= command.id %>",
102
+ "<%= config.bin %> <%= command.id %> --apply --limit 50"
132
103
  ],
133
- "flags": {},
134
- "hasDynamicHelp": false,
135
- "hiddenAliases": [],
136
- "id": "app:disable",
137
- "pluginAlias": "@memberjunction/cli",
138
- "pluginName": "@memberjunction/cli",
139
- "pluginType": "core",
140
- "strict": true,
141
- "enableJsonFlag": false,
142
- "isESM": true,
143
- "relativePath": [
144
- "dist",
145
- "commands",
146
- "app",
147
- "disable.js"
148
- ]
149
- },
150
- "app:enable": {
151
- "aliases": [],
152
- "args": {
153
- "name": {
154
- "description": "Name of the installed app to enable",
155
- "name": "name",
156
- "required": true
104
+ "flags": {
105
+ "conversation-id": {
106
+ "description": "Scope to artifacts attached to the given conversation.",
107
+ "name": "conversation-id",
108
+ "hasDynamicHelp": false,
109
+ "multiple": false,
110
+ "type": "option"
111
+ },
112
+ "since": {
113
+ "description": "Scope to artifacts created on/after this ISO date.",
114
+ "name": "since",
115
+ "hasDynamicHelp": false,
116
+ "multiple": false,
117
+ "type": "option"
118
+ },
119
+ "limit": {
120
+ "description": "Maximum number of rows to inspect.",
121
+ "name": "limit",
122
+ "default": 100,
123
+ "hasDynamicHelp": false,
124
+ "multiple": false,
125
+ "type": "option"
126
+ },
127
+ "apply": {
128
+ "description": "Write changes. Without this flag, this command only reports what it would do.",
129
+ "name": "apply",
130
+ "allowNo": false,
131
+ "type": "boolean"
132
+ },
133
+ "verbose": {
134
+ "char": "v",
135
+ "description": "Print every candidate row, not just the summary.",
136
+ "name": "verbose",
137
+ "allowNo": false,
138
+ "type": "boolean"
157
139
  }
158
140
  },
159
- "description": "Re-enable a disabled MJ Open App",
160
- "examples": [
161
- "<%= config.bin %> app enable acme-crm"
162
- ],
163
- "flags": {},
164
141
  "hasDynamicHelp": false,
165
142
  "hiddenAliases": [],
166
- "id": "app:enable",
143
+ "id": "artifacts:reclassify",
167
144
  "pluginAlias": "@memberjunction/cli",
168
145
  "pluginName": "@memberjunction/cli",
169
146
  "pluginType": "core",
@@ -173,27 +150,31 @@
173
150
  "relativePath": [
174
151
  "dist",
175
152
  "commands",
176
- "app",
177
- "enable.js"
153
+ "artifacts",
154
+ "reclassify.js"
178
155
  ]
179
156
  },
180
- "app:info": {
157
+ "artifacts:usage": {
181
158
  "aliases": [],
182
- "args": {
183
- "name": {
184
- "description": "Name of the installed app",
185
- "name": "name",
186
- "required": true
159
+ "args": {},
160
+ "description": "Show usage, flags, examples, and runtime hints for every `mj artifacts` command.",
161
+ "flags": {
162
+ "format": {
163
+ "description": "Output format. Defaults to text on a terminal and json when stdout is piped.",
164
+ "name": "format",
165
+ "hasDynamicHelp": false,
166
+ "multiple": false,
167
+ "options": [
168
+ "text",
169
+ "json",
170
+ "md"
171
+ ],
172
+ "type": "option"
187
173
  }
188
174
  },
189
- "description": "Show detailed information about an installed MJ Open App",
190
- "examples": [
191
- "<%= config.bin %> app info acme-crm"
192
- ],
193
- "flags": {},
194
175
  "hasDynamicHelp": false,
195
176
  "hiddenAliases": [],
196
- "id": "app:info",
177
+ "id": "artifacts:usage",
197
178
  "pluginAlias": "@memberjunction/cli",
198
179
  "pluginName": "@memberjunction/cli",
199
180
  "pluginType": "core",
@@ -203,58 +184,96 @@
203
184
  "relativePath": [
204
185
  "dist",
205
186
  "commands",
206
- "app",
207
- "info.js"
187
+ "artifacts",
188
+ "usage.js"
208
189
  ]
209
190
  },
210
- "app:install": {
191
+ "baseline:build": {
211
192
  "aliases": [],
212
- "args": {
213
- "source": {
214
- "description": "GitHub repository URL of the Open App. For a multi-app repo, append the in-repo path to the app (e.g. https://github.com/MemberJunction/Integrations/CRM/HubSpot).",
215
- "name": "source",
216
- "required": true
217
- }
218
- },
219
- "description": "Install an MJ Open App from a GitHub repository",
193
+ "args": {},
194
+ "description": "Generate a deterministic baseline SQL script from the END-STATE of a migrated MSSQL database.",
220
195
  "examples": [
221
- "<%= config.bin %> app install https://github.com/acme/mj-crm",
222
- "<%= config.bin %> app install https://github.com/acme/mj-crm --version 1.2.0",
223
- "<%= config.bin %> app install https://github.com/acme/mj-crm --verbose",
224
- "<%= config.bin %> app install https://github.com/MemberJunction/Integrations/CRM/HubSpot",
225
- "<%= config.bin %> app install https://github.com/acme/mj-crm --non-interactive"
196
+ "<%= config.bin %> <%= command.id %> --out ./migrations/v5/ # auto: within-major rebaseline",
197
+ "<%= config.bin %> <%= command.id %> --source-dir ./migrations/v5 --out ./migrations/v5/",
198
+ "<%= config.bin %> <%= command.id %> --baseline-version 6.0 --out ./migrations/v6/ # explicit major-boundary",
199
+ "<%= config.bin %> <%= command.id %> --baseline-version 5.32 --database MJ_BL_Stack --out /tmp/baseline/"
226
200
  ],
227
201
  "flags": {
228
- "version": {
229
- "description": "Specific version to install (default: latest)",
230
- "name": "version",
202
+ "baseline-version": {
203
+ "description": "Baseline version stamp in Major.Minor format (literal x is appended for patch, matching the V-file convention). Omit to auto-detect from --source-dir (within-major rebaseline mode).",
204
+ "name": "baseline-version",
231
205
  "hasDynamicHelp": false,
232
206
  "multiple": false,
233
207
  "type": "option"
234
208
  },
235
- "verbose": {
236
- "char": "v",
237
- "description": "Show detailed output",
238
- "name": "verbose",
209
+ "source-dir": {
210
+ "description": "Migrations source directory (e.g. ./migrations/v5). Used to auto-detect the next baseline version + timestamp when --baseline-version is omitted. Defaults to the highest migrations/v*/ directory walked up from cwd.",
211
+ "name": "source-dir",
212
+ "hasDynamicHelp": false,
213
+ "multiple": false,
214
+ "type": "option"
215
+ },
216
+ "description": {
217
+ "description": "Human-readable description embedded in the file header.",
218
+ "name": "description",
219
+ "default": "MemberJunction Baseline",
220
+ "hasDynamicHelp": false,
221
+ "multiple": false,
222
+ "type": "option"
223
+ },
224
+ "database": {
225
+ "description": "Override database name (host/user/password come from MJ config).",
226
+ "name": "database",
227
+ "hasDynamicHelp": false,
228
+ "multiple": false,
229
+ "type": "option"
230
+ },
231
+ "out": {
232
+ "description": "Output directory. Filename is auto-generated.",
233
+ "name": "out",
234
+ "default": ".",
235
+ "hasDynamicHelp": false,
236
+ "multiple": false,
237
+ "type": "option"
238
+ },
239
+ "exclude-data": {
240
+ "description": "Comma-separated list of tables (schema-qualified or not) to skip data dump for.",
241
+ "name": "exclude-data",
242
+ "default": "",
243
+ "hasDynamicHelp": false,
244
+ "multiple": false,
245
+ "type": "option"
246
+ },
247
+ "batch-size": {
248
+ "description": "Rows per INSERT batch.",
249
+ "name": "batch-size",
250
+ "default": 1000,
251
+ "hasDynamicHelp": false,
252
+ "multiple": false,
253
+ "type": "option"
254
+ },
255
+ "no-data": {
256
+ "description": "Emit schema only, no data inserts.",
257
+ "name": "no-data",
239
258
  "allowNo": false,
240
259
  "type": "boolean"
241
260
  },
242
- "non-interactive": {
243
- "description": "Skip interactive setup prompts; post-install hooks use environment variables / defaults (for CI/headless installs)",
244
- "name": "non-interactive",
261
+ "verbose": {
262
+ "description": "Print per-object progress.",
263
+ "name": "verbose",
245
264
  "allowNo": false,
246
265
  "type": "boolean"
247
266
  },
248
- "dangerously-ignore-dbl-underscore-schema-rule": {
249
- "hidden": true,
250
- "name": "dangerously-ignore-dbl-underscore-schema-rule",
267
+ "dry-run": {
268
+ "description": "Print to stdout instead of writing a file.",
269
+ "name": "dry-run",
251
270
  "allowNo": false,
252
271
  "type": "boolean"
253
272
  }
254
273
  },
255
274
  "hasDynamicHelp": false,
256
275
  "hiddenAliases": [],
257
- "id": "app:install",
276
+ "id": "baseline:build",
258
277
  "pluginAlias": "@memberjunction/cli",
259
278
  "pluginName": "@memberjunction/cli",
260
279
  "pluginType": "core",
@@ -264,306 +283,18 @@
264
283
  "relativePath": [
265
284
  "dist",
266
285
  "commands",
267
- "app",
268
- "install.js"
286
+ "baseline",
287
+ "build.js"
269
288
  ]
270
289
  },
271
- "app:list": {
290
+ "baseline:compare": {
272
291
  "aliases": [],
273
292
  "args": {},
274
- "description": "List all installed MJ Open Apps",
293
+ "description": "Deterministically compare two databases object-by-object and row-by-row.",
275
294
  "examples": [
276
- "<%= config.bin %> app list"
277
- ],
278
- "flags": {
279
- "verbose": {
280
- "char": "v",
281
- "description": "Show detailed output",
282
- "name": "verbose",
283
- "allowNo": false,
284
- "type": "boolean"
285
- }
286
- },
287
- "hasDynamicHelp": false,
288
- "hiddenAliases": [],
289
- "id": "app:list",
290
- "pluginAlias": "@memberjunction/cli",
291
- "pluginName": "@memberjunction/cli",
292
- "pluginType": "core",
293
- "strict": true,
294
- "enableJsonFlag": false,
295
- "isESM": true,
296
- "relativePath": [
297
- "dist",
298
- "commands",
299
- "app",
300
- "list.js"
301
- ]
302
- },
303
- "app:remove": {
304
- "aliases": [],
305
- "args": {
306
- "name": {
307
- "description": "Name of the installed app to remove",
308
- "name": "name",
309
- "required": true
310
- }
311
- },
312
- "description": "Remove an installed MJ Open App",
313
- "examples": [
314
- "<%= config.bin %> app remove acme-crm",
315
- "<%= config.bin %> app remove acme-crm --keep-data",
316
- "<%= config.bin %> app remove acme-crm --force"
317
- ],
318
- "flags": {
319
- "keep-data": {
320
- "description": "Keep the database schema and data",
321
- "name": "keep-data",
322
- "allowNo": false,
323
- "type": "boolean"
324
- },
325
- "force": {
326
- "description": "Force removal even if other apps depend on this one",
327
- "name": "force",
328
- "allowNo": false,
329
- "type": "boolean"
330
- },
331
- "yes": {
332
- "char": "y",
333
- "description": "Skip confirmation prompt",
334
- "name": "yes",
335
- "allowNo": false,
336
- "type": "boolean"
337
- },
338
- "verbose": {
339
- "char": "v",
340
- "description": "Show detailed output",
341
- "name": "verbose",
342
- "allowNo": false,
343
- "type": "boolean"
344
- },
345
- "dangerously-ignore-dbl-underscore-schema-rule": {
346
- "hidden": true,
347
- "name": "dangerously-ignore-dbl-underscore-schema-rule",
348
- "allowNo": false,
349
- "type": "boolean"
350
- }
351
- },
352
- "hasDynamicHelp": false,
353
- "hiddenAliases": [],
354
- "id": "app:remove",
355
- "pluginAlias": "@memberjunction/cli",
356
- "pluginName": "@memberjunction/cli",
357
- "pluginType": "core",
358
- "strict": true,
359
- "enableJsonFlag": false,
360
- "isESM": true,
361
- "relativePath": [
362
- "dist",
363
- "commands",
364
- "app",
365
- "remove.js"
366
- ]
367
- },
368
- "app:upgrade": {
369
- "aliases": [],
370
- "args": {
371
- "name": {
372
- "description": "Name of the installed app to upgrade",
373
- "name": "name",
374
- "required": true
375
- }
376
- },
377
- "description": "Upgrade an installed MJ Open App to a newer version",
378
- "examples": [
379
- "<%= config.bin %> app upgrade acme-crm",
380
- "<%= config.bin %> app upgrade acme-crm --version 1.3.0"
381
- ],
382
- "flags": {
383
- "version": {
384
- "description": "Specific version to upgrade to (default: latest)",
385
- "name": "version",
386
- "hasDynamicHelp": false,
387
- "multiple": false,
388
- "type": "option"
389
- },
390
- "verbose": {
391
- "char": "v",
392
- "description": "Show detailed output",
393
- "name": "verbose",
394
- "allowNo": false,
395
- "type": "boolean"
396
- },
397
- "non-interactive": {
398
- "description": "Skip interactive prompts; post-upgrade hooks use environment variables / defaults (for CI/headless upgrades)",
399
- "name": "non-interactive",
400
- "allowNo": false,
401
- "type": "boolean"
402
- },
403
- "dangerously-ignore-dbl-underscore-schema-rule": {
404
- "hidden": true,
405
- "name": "dangerously-ignore-dbl-underscore-schema-rule",
406
- "allowNo": false,
407
- "type": "boolean"
408
- }
409
- },
410
- "hasDynamicHelp": false,
411
- "hiddenAliases": [],
412
- "id": "app:upgrade",
413
- "pluginAlias": "@memberjunction/cli",
414
- "pluginName": "@memberjunction/cli",
415
- "pluginType": "core",
416
- "strict": true,
417
- "enableJsonFlag": false,
418
- "isESM": true,
419
- "relativePath": [
420
- "dist",
421
- "commands",
422
- "app",
423
- "upgrade.js"
424
- ]
425
- },
426
- "app:usage": {
427
- "aliases": [],
428
- "args": {},
429
- "description": "Show usage, flags, examples, and runtime hints for every `mj app` command.",
430
- "flags": {
431
- "format": {
432
- "description": "Output format. Defaults to text on a terminal and json when stdout is piped.",
433
- "name": "format",
434
- "hasDynamicHelp": false,
435
- "multiple": false,
436
- "options": [
437
- "text",
438
- "json",
439
- "md"
440
- ],
441
- "type": "option"
442
- }
443
- },
444
- "hasDynamicHelp": false,
445
- "hiddenAliases": [],
446
- "id": "app:usage",
447
- "pluginAlias": "@memberjunction/cli",
448
- "pluginName": "@memberjunction/cli",
449
- "pluginType": "core",
450
- "strict": true,
451
- "enableJsonFlag": false,
452
- "isESM": true,
453
- "relativePath": [
454
- "dist",
455
- "commands",
456
- "app",
457
- "usage.js"
458
- ]
459
- },
460
- "baseline:build": {
461
- "aliases": [],
462
- "args": {},
463
- "description": "Generate a deterministic baseline SQL script from the END-STATE of a migrated MSSQL database.",
464
- "examples": [
465
- "<%= config.bin %> <%= command.id %> --out ./migrations/v5/ # auto: within-major rebaseline",
466
- "<%= config.bin %> <%= command.id %> --source-dir ./migrations/v5 --out ./migrations/v5/",
467
- "<%= config.bin %> <%= command.id %> --baseline-version 6.0 --out ./migrations/v6/ # explicit major-boundary",
468
- "<%= config.bin %> <%= command.id %> --baseline-version 5.32 --database MJ_BL_Stack --out /tmp/baseline/"
469
- ],
470
- "flags": {
471
- "baseline-version": {
472
- "description": "Baseline version stamp in Major.Minor format (literal x is appended for patch, matching the V-file convention). Omit to auto-detect from --source-dir (within-major rebaseline mode).",
473
- "name": "baseline-version",
474
- "hasDynamicHelp": false,
475
- "multiple": false,
476
- "type": "option"
477
- },
478
- "source-dir": {
479
- "description": "Migrations source directory (e.g. ./migrations/v5). Used to auto-detect the next baseline version + timestamp when --baseline-version is omitted. Defaults to the highest migrations/v*/ directory walked up from cwd.",
480
- "name": "source-dir",
481
- "hasDynamicHelp": false,
482
- "multiple": false,
483
- "type": "option"
484
- },
485
- "description": {
486
- "description": "Human-readable description embedded in the file header.",
487
- "name": "description",
488
- "default": "MemberJunction Baseline",
489
- "hasDynamicHelp": false,
490
- "multiple": false,
491
- "type": "option"
492
- },
493
- "database": {
494
- "description": "Override database name (host/user/password come from MJ config).",
495
- "name": "database",
496
- "hasDynamicHelp": false,
497
- "multiple": false,
498
- "type": "option"
499
- },
500
- "out": {
501
- "description": "Output directory. Filename is auto-generated.",
502
- "name": "out",
503
- "default": ".",
504
- "hasDynamicHelp": false,
505
- "multiple": false,
506
- "type": "option"
507
- },
508
- "exclude-data": {
509
- "description": "Comma-separated list of tables (schema-qualified or not) to skip data dump for.",
510
- "name": "exclude-data",
511
- "default": "",
512
- "hasDynamicHelp": false,
513
- "multiple": false,
514
- "type": "option"
515
- },
516
- "batch-size": {
517
- "description": "Rows per INSERT batch.",
518
- "name": "batch-size",
519
- "default": 1000,
520
- "hasDynamicHelp": false,
521
- "multiple": false,
522
- "type": "option"
523
- },
524
- "no-data": {
525
- "description": "Emit schema only, no data inserts.",
526
- "name": "no-data",
527
- "allowNo": false,
528
- "type": "boolean"
529
- },
530
- "verbose": {
531
- "description": "Print per-object progress.",
532
- "name": "verbose",
533
- "allowNo": false,
534
- "type": "boolean"
535
- },
536
- "dry-run": {
537
- "description": "Print to stdout instead of writing a file.",
538
- "name": "dry-run",
539
- "allowNo": false,
540
- "type": "boolean"
541
- }
542
- },
543
- "hasDynamicHelp": false,
544
- "hiddenAliases": [],
545
- "id": "baseline:build",
546
- "pluginAlias": "@memberjunction/cli",
547
- "pluginName": "@memberjunction/cli",
548
- "pluginType": "core",
549
- "strict": true,
550
- "enableJsonFlag": false,
551
- "isESM": true,
552
- "relativePath": [
553
- "dist",
554
- "commands",
555
- "baseline",
556
- "build.js"
557
- ]
558
- },
559
- "baseline:compare": {
560
- "aliases": [],
561
- "args": {},
562
- "description": "Deterministically compare two databases object-by-object and row-by-row.",
563
- "examples": [
564
- "<%= config.bin %> <%= command.id %> --left MJ_BL_Stack --right MJ_BL_New",
565
- "<%= config.bin %> <%= command.id %> --left A --right B --row-compare counts",
566
- "<%= config.bin %> <%= command.id %> --left A --right B --fail-on-diff --out ./diffs/"
295
+ "<%= config.bin %> <%= command.id %> --left MJ_BL_Stack --right MJ_BL_New",
296
+ "<%= config.bin %> <%= command.id %> --left A --right B --row-compare counts",
297
+ "<%= config.bin %> <%= command.id %> --left A --right B --fail-on-diff --out ./diffs/"
567
298
  ],
568
299
  "flags": {
569
300
  "left": {
@@ -781,7 +512,201 @@
781
512
  },
782
513
  "hasDynamicHelp": false,
783
514
  "hiddenAliases": [],
784
- "id": "baseline:roundtrip",
515
+ "id": "baseline:roundtrip",
516
+ "pluginAlias": "@memberjunction/cli",
517
+ "pluginName": "@memberjunction/cli",
518
+ "pluginType": "core",
519
+ "strict": true,
520
+ "enableJsonFlag": false,
521
+ "isESM": true,
522
+ "relativePath": [
523
+ "dist",
524
+ "commands",
525
+ "baseline",
526
+ "roundtrip.js"
527
+ ]
528
+ },
529
+ "baseline:usage": {
530
+ "aliases": [],
531
+ "args": {},
532
+ "description": "Show usage, flags, examples, and runtime hints for every `mj baseline` command.",
533
+ "flags": {
534
+ "format": {
535
+ "description": "Output format. Defaults to text on a terminal and json when stdout is piped.",
536
+ "name": "format",
537
+ "hasDynamicHelp": false,
538
+ "multiple": false,
539
+ "options": [
540
+ "text",
541
+ "json",
542
+ "md"
543
+ ],
544
+ "type": "option"
545
+ }
546
+ },
547
+ "hasDynamicHelp": false,
548
+ "hiddenAliases": [],
549
+ "id": "baseline:usage",
550
+ "pluginAlias": "@memberjunction/cli",
551
+ "pluginName": "@memberjunction/cli",
552
+ "pluginType": "core",
553
+ "strict": true,
554
+ "enableJsonFlag": false,
555
+ "isESM": true,
556
+ "relativePath": [
557
+ "dist",
558
+ "commands",
559
+ "baseline",
560
+ "usage.js"
561
+ ]
562
+ },
563
+ "bump": {
564
+ "aliases": [],
565
+ "args": {},
566
+ "description": "Bumps MemberJunction dependency versions",
567
+ "examples": [
568
+ {
569
+ "command": "<%= config.bin %> <%= command.id %>",
570
+ "description": "Bump all @memberjunction/* dependencies in the current directory's package.json to the CLI version"
571
+ },
572
+ {
573
+ "command": "<%= config.bin %> <%= command.id %> -rdv",
574
+ "description": "Preview all recursive packages bumps without writing any changes."
575
+ },
576
+ {
577
+ "command": "<%= config.bin %> <%= command.id %> -rqt v2.10.0 | xargs -n1 -I{} npm install --prefix {}",
578
+ "description": "Recursively bump all @memberjunction/* dependencies in all packages to version v2.10.0 and output only the paths containing the updated package.json files. Pipe the output to xargs to run npm install in each directory and update the package-lock.json files as well."
579
+ }
580
+ ],
581
+ "flags": {
582
+ "verbose": {
583
+ "char": "v",
584
+ "description": "Enable additional logging",
585
+ "name": "verbose",
586
+ "allowNo": false,
587
+ "type": "boolean"
588
+ },
589
+ "recursive": {
590
+ "char": "r",
591
+ "description": "Bump version in current directory and all subdirectories",
592
+ "name": "recursive",
593
+ "allowNo": false,
594
+ "type": "boolean"
595
+ },
596
+ "tag": {
597
+ "char": "t",
598
+ "description": "Version tag to bump target for bump (e.g. v2.10.0), defaults to the CLI version",
599
+ "name": "tag",
600
+ "hasDynamicHelp": false,
601
+ "multiple": false,
602
+ "type": "option"
603
+ },
604
+ "quiet": {
605
+ "char": "q",
606
+ "description": "Only output paths for updated packages",
607
+ "name": "quiet",
608
+ "allowNo": false,
609
+ "type": "boolean"
610
+ },
611
+ "dry": {
612
+ "char": "d",
613
+ "description": "Dry run, do not write changes to package.json files",
614
+ "name": "dry",
615
+ "allowNo": false,
616
+ "type": "boolean"
617
+ }
618
+ },
619
+ "hasDynamicHelp": false,
620
+ "hiddenAliases": [],
621
+ "id": "bump",
622
+ "pluginAlias": "@memberjunction/cli",
623
+ "pluginName": "@memberjunction/cli",
624
+ "pluginType": "core",
625
+ "strict": true,
626
+ "enableJsonFlag": false,
627
+ "isESM": true,
628
+ "relativePath": [
629
+ "dist",
630
+ "commands",
631
+ "bump",
632
+ "index.js"
633
+ ]
634
+ },
635
+ "bump:usage": {
636
+ "aliases": [],
637
+ "args": {},
638
+ "description": "Show usage, flags, examples, and runtime hints for every `mj bump` command.",
639
+ "flags": {
640
+ "format": {
641
+ "description": "Output format. Defaults to text on a terminal and json when stdout is piped.",
642
+ "name": "format",
643
+ "hasDynamicHelp": false,
644
+ "multiple": false,
645
+ "options": [
646
+ "text",
647
+ "json",
648
+ "md"
649
+ ],
650
+ "type": "option"
651
+ }
652
+ },
653
+ "hasDynamicHelp": false,
654
+ "hiddenAliases": [],
655
+ "id": "bump:usage",
656
+ "pluginAlias": "@memberjunction/cli",
657
+ "pluginName": "@memberjunction/cli",
658
+ "pluginType": "core",
659
+ "strict": true,
660
+ "enableJsonFlag": false,
661
+ "isESM": true,
662
+ "relativePath": [
663
+ "dist",
664
+ "commands",
665
+ "bump",
666
+ "usage.js"
667
+ ]
668
+ },
669
+ "app:check-updates": {
670
+ "aliases": [],
671
+ "args": {},
672
+ "description": "Check for available upgrades for installed MJ Open Apps",
673
+ "examples": [
674
+ "<%= config.bin %> app check-updates"
675
+ ],
676
+ "flags": {},
677
+ "hasDynamicHelp": false,
678
+ "hiddenAliases": [],
679
+ "id": "app:check-updates",
680
+ "pluginAlias": "@memberjunction/cli",
681
+ "pluginName": "@memberjunction/cli",
682
+ "pluginType": "core",
683
+ "strict": true,
684
+ "enableJsonFlag": false,
685
+ "isESM": true,
686
+ "relativePath": [
687
+ "dist",
688
+ "commands",
689
+ "app",
690
+ "check-updates.js"
691
+ ]
692
+ },
693
+ "app:disable": {
694
+ "aliases": [],
695
+ "args": {
696
+ "name": {
697
+ "description": "Name of the installed app to disable",
698
+ "name": "name",
699
+ "required": true
700
+ }
701
+ },
702
+ "description": "Disable an installed MJ Open App without removing it",
703
+ "examples": [
704
+ "<%= config.bin %> app disable acme-crm"
705
+ ],
706
+ "flags": {},
707
+ "hasDynamicHelp": false,
708
+ "hiddenAliases": [],
709
+ "id": "app:disable",
785
710
  "pluginAlias": "@memberjunction/cli",
786
711
  "pluginName": "@memberjunction/cli",
787
712
  "pluginType": "core",
@@ -791,31 +716,27 @@
791
716
  "relativePath": [
792
717
  "dist",
793
718
  "commands",
794
- "baseline",
795
- "roundtrip.js"
719
+ "app",
720
+ "disable.js"
796
721
  ]
797
722
  },
798
- "baseline:usage": {
723
+ "app:enable": {
799
724
  "aliases": [],
800
- "args": {},
801
- "description": "Show usage, flags, examples, and runtime hints for every `mj baseline` command.",
802
- "flags": {
803
- "format": {
804
- "description": "Output format. Defaults to text on a terminal and json when stdout is piped.",
805
- "name": "format",
806
- "hasDynamicHelp": false,
807
- "multiple": false,
808
- "options": [
809
- "text",
810
- "json",
811
- "md"
812
- ],
813
- "type": "option"
725
+ "args": {
726
+ "name": {
727
+ "description": "Name of the installed app to enable",
728
+ "name": "name",
729
+ "required": true
814
730
  }
815
731
  },
732
+ "description": "Re-enable a disabled MJ Open App",
733
+ "examples": [
734
+ "<%= config.bin %> app enable acme-crm"
735
+ ],
736
+ "flags": {},
816
737
  "hasDynamicHelp": false,
817
738
  "hiddenAliases": [],
818
- "id": "baseline:usage",
739
+ "id": "app:enable",
819
740
  "pluginAlias": "@memberjunction/cli",
820
741
  "pluginName": "@memberjunction/cli",
821
742
  "pluginType": "core",
@@ -825,58 +746,88 @@
825
746
  "relativePath": [
826
747
  "dist",
827
748
  "commands",
828
- "baseline",
829
- "usage.js"
749
+ "app",
750
+ "enable.js"
830
751
  ]
831
752
  },
832
- "artifacts:reclassify": {
753
+ "app:info": {
833
754
  "aliases": [],
834
- "args": {},
835
- "description": "Upgrade-recovery utility for v5.35 artifact unification. Re-evaluates rows whose TypeID is the deleted JSON fallback but whose actual content does not parse as JSON. Normally a no-op: the v5.35 backfill migration handles this automatically. This command is only relevant when the migration ran BEFORE the artifact-type metadata (Generic Text / Generic Binary) was pushed via `mj sync push`, in which case the migration prints a notice telling you to run this. Reports \"no candidates\" once everything is reconciled. Dry-run by default; --apply writes through Record Changes.",
755
+ "args": {
756
+ "name": {
757
+ "description": "Name of the installed app",
758
+ "name": "name",
759
+ "required": true
760
+ }
761
+ },
762
+ "description": "Show detailed information about an installed MJ Open App",
836
763
  "examples": [
837
- "<%= config.bin %> <%= command.id %>",
838
- "<%= config.bin %> <%= command.id %> --apply --limit 50"
764
+ "<%= config.bin %> app info acme-crm"
765
+ ],
766
+ "flags": {},
767
+ "hasDynamicHelp": false,
768
+ "hiddenAliases": [],
769
+ "id": "app:info",
770
+ "pluginAlias": "@memberjunction/cli",
771
+ "pluginName": "@memberjunction/cli",
772
+ "pluginType": "core",
773
+ "strict": true,
774
+ "enableJsonFlag": false,
775
+ "isESM": true,
776
+ "relativePath": [
777
+ "dist",
778
+ "commands",
779
+ "app",
780
+ "info.js"
781
+ ]
782
+ },
783
+ "app:install": {
784
+ "aliases": [],
785
+ "args": {
786
+ "source": {
787
+ "description": "GitHub repository URL of the Open App. For a multi-app repo, append the in-repo path to the app (e.g. https://github.com/MemberJunction/Integrations/CRM/HubSpot).",
788
+ "name": "source",
789
+ "required": true
790
+ }
791
+ },
792
+ "description": "Install an MJ Open App from a GitHub repository",
793
+ "examples": [
794
+ "<%= config.bin %> app install https://github.com/acme/mj-crm",
795
+ "<%= config.bin %> app install https://github.com/acme/mj-crm --version 1.2.0",
796
+ "<%= config.bin %> app install https://github.com/acme/mj-crm --verbose",
797
+ "<%= config.bin %> app install https://github.com/MemberJunction/Integrations/CRM/HubSpot",
798
+ "<%= config.bin %> app install https://github.com/acme/mj-crm --non-interactive"
839
799
  ],
840
800
  "flags": {
841
- "conversation-id": {
842
- "description": "Scope to artifacts attached to the given conversation.",
843
- "name": "conversation-id",
844
- "hasDynamicHelp": false,
845
- "multiple": false,
846
- "type": "option"
847
- },
848
- "since": {
849
- "description": "Scope to artifacts created on/after this ISO date.",
850
- "name": "since",
801
+ "version": {
802
+ "description": "Specific version to install (default: latest)",
803
+ "name": "version",
851
804
  "hasDynamicHelp": false,
852
805
  "multiple": false,
853
806
  "type": "option"
854
807
  },
855
- "limit": {
856
- "description": "Maximum number of rows to inspect.",
857
- "name": "limit",
858
- "default": 100,
859
- "hasDynamicHelp": false,
860
- "multiple": false,
861
- "type": "option"
808
+ "verbose": {
809
+ "char": "v",
810
+ "description": "Show detailed output",
811
+ "name": "verbose",
812
+ "allowNo": false,
813
+ "type": "boolean"
862
814
  },
863
- "apply": {
864
- "description": "Write changes. Without this flag, this command only reports what it would do.",
865
- "name": "apply",
815
+ "non-interactive": {
816
+ "description": "Skip interactive setup prompts; post-install hooks use environment variables / defaults (for CI/headless installs)",
817
+ "name": "non-interactive",
866
818
  "allowNo": false,
867
819
  "type": "boolean"
868
820
  },
869
- "verbose": {
870
- "char": "v",
871
- "description": "Print every candidate row, not just the summary.",
872
- "name": "verbose",
821
+ "dangerously-ignore-dbl-underscore-schema-rule": {
822
+ "hidden": true,
823
+ "name": "dangerously-ignore-dbl-underscore-schema-rule",
873
824
  "allowNo": false,
874
825
  "type": "boolean"
875
826
  }
876
827
  },
877
828
  "hasDynamicHelp": false,
878
829
  "hiddenAliases": [],
879
- "id": "artifacts:reclassify",
830
+ "id": "app:install",
880
831
  "pluginAlias": "@memberjunction/cli",
881
832
  "pluginName": "@memberjunction/cli",
882
833
  "pluginType": "core",
@@ -886,31 +837,29 @@
886
837
  "relativePath": [
887
838
  "dist",
888
839
  "commands",
889
- "artifacts",
890
- "reclassify.js"
840
+ "app",
841
+ "install.js"
891
842
  ]
892
843
  },
893
- "artifacts:usage": {
844
+ "app:list": {
894
845
  "aliases": [],
895
846
  "args": {},
896
- "description": "Show usage, flags, examples, and runtime hints for every `mj artifacts` command.",
847
+ "description": "List all installed MJ Open Apps",
848
+ "examples": [
849
+ "<%= config.bin %> app list"
850
+ ],
897
851
  "flags": {
898
- "format": {
899
- "description": "Output format. Defaults to text on a terminal and json when stdout is piped.",
900
- "name": "format",
901
- "hasDynamicHelp": false,
902
- "multiple": false,
903
- "options": [
904
- "text",
905
- "json",
906
- "md"
907
- ],
908
- "type": "option"
852
+ "verbose": {
853
+ "char": "v",
854
+ "description": "Show detailed output",
855
+ "name": "verbose",
856
+ "allowNo": false,
857
+ "type": "boolean"
909
858
  }
910
859
  },
911
860
  "hasDynamicHelp": false,
912
861
  "hiddenAliases": [],
913
- "id": "artifacts:usage",
862
+ "id": "app:list",
914
863
  "pluginAlias": "@memberjunction/cli",
915
864
  "pluginName": "@memberjunction/cli",
916
865
  "pluginType": "core",
@@ -920,69 +869,120 @@
920
869
  "relativePath": [
921
870
  "dist",
922
871
  "commands",
923
- "artifacts",
924
- "usage.js"
872
+ "app",
873
+ "list.js"
925
874
  ]
926
875
  },
927
- "bump": {
876
+ "app:remove": {
928
877
  "aliases": [],
929
- "args": {},
930
- "description": "Bumps MemberJunction dependency versions",
878
+ "args": {
879
+ "name": {
880
+ "description": "Name of the installed app to remove",
881
+ "name": "name",
882
+ "required": true
883
+ }
884
+ },
885
+ "description": "Remove an installed MJ Open App",
931
886
  "examples": [
932
- {
933
- "command": "<%= config.bin %> <%= command.id %>",
934
- "description": "Bump all @memberjunction/* dependencies in the current directory's package.json to the CLI version"
887
+ "<%= config.bin %> app remove acme-crm",
888
+ "<%= config.bin %> app remove acme-crm --keep-data",
889
+ "<%= config.bin %> app remove acme-crm --force"
890
+ ],
891
+ "flags": {
892
+ "keep-data": {
893
+ "description": "Keep the database schema and data",
894
+ "name": "keep-data",
895
+ "allowNo": false,
896
+ "type": "boolean"
935
897
  },
936
- {
937
- "command": "<%= config.bin %> <%= command.id %> -rdv",
938
- "description": "Preview all recursive packages bumps without writing any changes."
898
+ "force": {
899
+ "description": "Force removal even if other apps depend on this one",
900
+ "name": "force",
901
+ "allowNo": false,
902
+ "type": "boolean"
939
903
  },
940
- {
941
- "command": "<%= config.bin %> <%= command.id %> -rqt v2.10.0 | xargs -n1 -I{} npm install --prefix {}",
942
- "description": "Recursively bump all @memberjunction/* dependencies in all packages to version v2.10.0 and output only the paths containing the updated package.json files. Pipe the output to xargs to run npm install in each directory and update the package-lock.json files as well."
904
+ "yes": {
905
+ "char": "y",
906
+ "description": "Skip confirmation prompt",
907
+ "name": "yes",
908
+ "allowNo": false,
909
+ "type": "boolean"
910
+ },
911
+ "verbose": {
912
+ "char": "v",
913
+ "description": "Show detailed output",
914
+ "name": "verbose",
915
+ "allowNo": false,
916
+ "type": "boolean"
917
+ },
918
+ "dangerously-ignore-dbl-underscore-schema-rule": {
919
+ "hidden": true,
920
+ "name": "dangerously-ignore-dbl-underscore-schema-rule",
921
+ "allowNo": false,
922
+ "type": "boolean"
923
+ }
924
+ },
925
+ "hasDynamicHelp": false,
926
+ "hiddenAliases": [],
927
+ "id": "app:remove",
928
+ "pluginAlias": "@memberjunction/cli",
929
+ "pluginName": "@memberjunction/cli",
930
+ "pluginType": "core",
931
+ "strict": true,
932
+ "enableJsonFlag": false,
933
+ "isESM": true,
934
+ "relativePath": [
935
+ "dist",
936
+ "commands",
937
+ "app",
938
+ "remove.js"
939
+ ]
940
+ },
941
+ "app:upgrade": {
942
+ "aliases": [],
943
+ "args": {
944
+ "name": {
945
+ "description": "Name of the installed app to upgrade",
946
+ "name": "name",
947
+ "required": true
943
948
  }
949
+ },
950
+ "description": "Upgrade an installed MJ Open App to a newer version",
951
+ "examples": [
952
+ "<%= config.bin %> app upgrade acme-crm",
953
+ "<%= config.bin %> app upgrade acme-crm --version 1.3.0"
944
954
  ],
945
955
  "flags": {
956
+ "version": {
957
+ "description": "Specific version to upgrade to (default: latest)",
958
+ "name": "version",
959
+ "hasDynamicHelp": false,
960
+ "multiple": false,
961
+ "type": "option"
962
+ },
946
963
  "verbose": {
947
964
  "char": "v",
948
- "description": "Enable additional logging",
965
+ "description": "Show detailed output",
949
966
  "name": "verbose",
950
967
  "allowNo": false,
951
968
  "type": "boolean"
952
969
  },
953
- "recursive": {
954
- "char": "r",
955
- "description": "Bump version in current directory and all subdirectories",
956
- "name": "recursive",
957
- "allowNo": false,
958
- "type": "boolean"
959
- },
960
- "tag": {
961
- "char": "t",
962
- "description": "Version tag to bump target for bump (e.g. v2.10.0), defaults to the CLI version",
963
- "name": "tag",
964
- "hasDynamicHelp": false,
965
- "multiple": false,
966
- "type": "option"
967
- },
968
- "quiet": {
969
- "char": "q",
970
- "description": "Only output paths for updated packages",
971
- "name": "quiet",
970
+ "non-interactive": {
971
+ "description": "Skip interactive prompts; post-upgrade hooks use environment variables / defaults (for CI/headless upgrades)",
972
+ "name": "non-interactive",
972
973
  "allowNo": false,
973
974
  "type": "boolean"
974
975
  },
975
- "dry": {
976
- "char": "d",
977
- "description": "Dry run, do not write changes to package.json files",
978
- "name": "dry",
976
+ "dangerously-ignore-dbl-underscore-schema-rule": {
977
+ "hidden": true,
978
+ "name": "dangerously-ignore-dbl-underscore-schema-rule",
979
979
  "allowNo": false,
980
980
  "type": "boolean"
981
981
  }
982
982
  },
983
983
  "hasDynamicHelp": false,
984
984
  "hiddenAliases": [],
985
- "id": "bump",
985
+ "id": "app:upgrade",
986
986
  "pluginAlias": "@memberjunction/cli",
987
987
  "pluginName": "@memberjunction/cli",
988
988
  "pluginType": "core",
@@ -992,14 +992,14 @@
992
992
  "relativePath": [
993
993
  "dist",
994
994
  "commands",
995
- "bump",
996
- "index.js"
995
+ "app",
996
+ "upgrade.js"
997
997
  ]
998
998
  },
999
- "bump:usage": {
999
+ "app:usage": {
1000
1000
  "aliases": [],
1001
1001
  "args": {},
1002
- "description": "Show usage, flags, examples, and runtime hints for every `mj bump` command.",
1002
+ "description": "Show usage, flags, examples, and runtime hints for every `mj app` command.",
1003
1003
  "flags": {
1004
1004
  "format": {
1005
1005
  "description": "Output format. Defaults to text on a terminal and json when stdout is piped.",
@@ -1016,7 +1016,7 @@
1016
1016
  },
1017
1017
  "hasDynamicHelp": false,
1018
1018
  "hiddenAliases": [],
1019
- "id": "bump:usage",
1019
+ "id": "app:usage",
1020
1020
  "pluginAlias": "@memberjunction/cli",
1021
1021
  "pluginName": "@memberjunction/cli",
1022
1022
  "pluginType": "core",
@@ -1026,7 +1026,7 @@
1026
1026
  "relativePath": [
1027
1027
  "dist",
1028
1028
  "commands",
1029
- "bump",
1029
+ "app",
1030
1030
  "usage.js"
1031
1031
  ]
1032
1032
  },
@@ -1488,6 +1488,12 @@
1488
1488
  "allowNo": false,
1489
1489
  "type": "boolean"
1490
1490
  },
1491
+ "no-app-packages": {
1492
+ "description": "Do not load installed Open App server packages (or the host's generated packages) for this run, so records are written with the generic BaseEntity — no custom Save() logic or lifecycle hooks.",
1493
+ "name": "no-app-packages",
1494
+ "allowNo": false,
1495
+ "type": "boolean"
1496
+ },
1491
1497
  "interactive": {
1492
1498
  "description": "Allow interactive prompts. Defaults to on at a terminal and off when piped, spawned, or in CI, so an agent never hangs on a question. Use --no-interactive to force it off.",
1493
1499
  "name": "interactive",
@@ -1511,6 +1517,25 @@
1511
1517
  "name": "force-advanced-gen",
1512
1518
  "allowNo": false,
1513
1519
  "type": "boolean"
1520
+ },
1521
+ "no-ai": {
1522
+ "description": "Disable AI-driven advanced generation (descriptions, categories, search ranking). Overrides config and credential checks. Can also be set with MJ_CODEGEN_NO_AI=1.",
1523
+ "name": "no-ai",
1524
+ "allowNo": false,
1525
+ "type": "boolean"
1526
+ },
1527
+ "sql-output-dir": {
1528
+ "description": "Directory for CodeGen_Run_*.sql (EntityField INSERTs and other metadata SQL). Open Apps default to ./migrations/codegen. Do not point this at MJ/migrations/v*.",
1529
+ "name": "sql-output-dir",
1530
+ "hasDynamicHelp": false,
1531
+ "multiple": false,
1532
+ "type": "option"
1533
+ },
1534
+ "skip-commands": {
1535
+ "description": "Skip running BEFORE and AFTER shell commands configured in mj.config. Can also be set with MJ_CODEGEN_SKIP_COMMANDS=1.",
1536
+ "name": "skip-commands",
1537
+ "allowNo": false,
1538
+ "type": "boolean"
1514
1539
  }
1515
1540
  },
1516
1541
  "hasDynamicHelp": false,
@@ -1542,6 +1567,21 @@
1542
1567
  "type": "boolean",
1543
1568
  "description": "Re-run advanced generation for all entities"
1544
1569
  },
1570
+ {
1571
+ "name": "--no-ai",
1572
+ "type": "boolean",
1573
+ "description": "Disable AI-driven advanced generation (same as MJ_CODEGEN_NO_AI=1)"
1574
+ },
1575
+ {
1576
+ "name": "--skip-commands",
1577
+ "type": "boolean",
1578
+ "description": "Skip running BEFORE/AFTER commands (same as MJ_CODEGEN_SKIP_COMMANDS=1)"
1579
+ },
1580
+ {
1581
+ "name": "--sql-output-dir",
1582
+ "type": "string",
1583
+ "description": "Directory for CodeGen_Run metadata SQL (Open Apps: ./migrations/codegen)"
1584
+ },
1545
1585
  {
1546
1586
  "name": "--format",
1547
1587
  "type": "text|json|md",
@@ -1551,6 +1591,7 @@
1551
1591
  "examples": [
1552
1592
  "mj codegen",
1553
1593
  "mj codegen --skipdb",
1594
+ "mj codegen --skip-commands",
1554
1595
  "mj codegen --format=json"
1555
1596
  ],
1556
1597
  "runtime": {
@@ -2613,84 +2654,6 @@
2613
2654
  "usage.js"
2614
2655
  ]
2615
2656
  },
2616
- "plugin:add": {
2617
- "aliases": [],
2618
- "args": {
2619
- "package": {
2620
- "description": "Plugin entry-point specifier (package name, subpath, or relative path)",
2621
- "name": "package",
2622
- "required": true
2623
- }
2624
- },
2625
- "description": "Register a CLI plugin package in mj-cli-plugins.json so `mj` loads it at startup.",
2626
- "examples": [
2627
- "<%= config.bin %> <%= command.id %> @my-org/mj-plugin/plugins",
2628
- "<%= config.bin %> <%= command.id %> ./local-plugins/my-tool"
2629
- ],
2630
- "flags": {
2631
- "format": {
2632
- "description": "Output format",
2633
- "name": "format",
2634
- "default": "text",
2635
- "hasDynamicHelp": false,
2636
- "multiple": false,
2637
- "options": [
2638
- "text",
2639
- "json"
2640
- ],
2641
- "type": "option"
2642
- }
2643
- },
2644
- "hasDynamicHelp": false,
2645
- "hiddenAliases": [],
2646
- "id": "plugin:add",
2647
- "pluginAlias": "@memberjunction/cli",
2648
- "pluginName": "@memberjunction/cli",
2649
- "pluginType": "core",
2650
- "strict": true,
2651
- "enableJsonFlag": false,
2652
- "isESM": true,
2653
- "relativePath": [
2654
- "dist",
2655
- "commands",
2656
- "plugin",
2657
- "add.js"
2658
- ]
2659
- },
2660
- "plugin:usage": {
2661
- "aliases": [],
2662
- "args": {},
2663
- "description": "Show usage, flags, examples, and runtime hints for every `mj plugin` command.",
2664
- "flags": {
2665
- "format": {
2666
- "description": "Output format. Defaults to text on a terminal and json when stdout is piped.",
2667
- "name": "format",
2668
- "hasDynamicHelp": false,
2669
- "multiple": false,
2670
- "options": [
2671
- "text",
2672
- "json",
2673
- "md"
2674
- ],
2675
- "type": "option"
2676
- }
2677
- },
2678
- "hasDynamicHelp": false,
2679
- "hiddenAliases": [],
2680
- "id": "plugin:usage",
2681
- "pluginAlias": "@memberjunction/cli",
2682
- "pluginName": "@memberjunction/cli",
2683
- "pluginType": "core",
2684
- "strict": true,
2685
- "enableJsonFlag": false,
2686
- "isESM": true,
2687
- "relativePath": [
2688
- "dist",
2689
- "commands",
2690
- "plugin",
2691
- "usage.js"
2692
- ]
2693
- },
2694
2657
  "migrate:convert": {
2695
2658
  "aliases": [],
2696
2659
  "args": {},
@@ -2972,17 +2935,95 @@
2972
2935
  "hasDynamicHelp": false,
2973
2936
  "multiple": false,
2974
2937
  "type": "option"
2975
- },
2976
- "dry-run": {
2977
- "description": "Report what would be re-baked without writing files",
2978
- "name": "dry-run",
2979
- "allowNo": false,
2980
- "type": "boolean"
2938
+ },
2939
+ "dry-run": {
2940
+ "description": "Report what would be re-baked without writing files",
2941
+ "name": "dry-run",
2942
+ "allowNo": false,
2943
+ "type": "boolean"
2944
+ }
2945
+ },
2946
+ "hasDynamicHelp": false,
2947
+ "hiddenAliases": [],
2948
+ "id": "migrate:rebake",
2949
+ "pluginAlias": "@memberjunction/cli",
2950
+ "pluginName": "@memberjunction/cli",
2951
+ "pluginType": "core",
2952
+ "strict": true,
2953
+ "enableJsonFlag": false,
2954
+ "isESM": true,
2955
+ "relativePath": [
2956
+ "dist",
2957
+ "commands",
2958
+ "migrate",
2959
+ "rebake.js"
2960
+ ]
2961
+ },
2962
+ "migrate:usage": {
2963
+ "aliases": [],
2964
+ "args": {},
2965
+ "description": "Show usage, flags, examples, and runtime hints for every `mj migrate` command.",
2966
+ "flags": {
2967
+ "format": {
2968
+ "description": "Output format. Defaults to text on a terminal and json when stdout is piped.",
2969
+ "name": "format",
2970
+ "hasDynamicHelp": false,
2971
+ "multiple": false,
2972
+ "options": [
2973
+ "text",
2974
+ "json",
2975
+ "md"
2976
+ ],
2977
+ "type": "option"
2978
+ }
2979
+ },
2980
+ "hasDynamicHelp": false,
2981
+ "hiddenAliases": [],
2982
+ "id": "migrate:usage",
2983
+ "pluginAlias": "@memberjunction/cli",
2984
+ "pluginName": "@memberjunction/cli",
2985
+ "pluginType": "core",
2986
+ "strict": true,
2987
+ "enableJsonFlag": false,
2988
+ "isESM": true,
2989
+ "relativePath": [
2990
+ "dist",
2991
+ "commands",
2992
+ "migrate",
2993
+ "usage.js"
2994
+ ]
2995
+ },
2996
+ "plugin:add": {
2997
+ "aliases": [],
2998
+ "args": {
2999
+ "package": {
3000
+ "description": "Plugin entry-point specifier (package name, subpath, or relative path)",
3001
+ "name": "package",
3002
+ "required": true
3003
+ }
3004
+ },
3005
+ "description": "Register a CLI plugin package in mj-cli-plugins.json so `mj` loads it at startup.",
3006
+ "examples": [
3007
+ "<%= config.bin %> <%= command.id %> @my-org/mj-plugin/plugins",
3008
+ "<%= config.bin %> <%= command.id %> ./local-plugins/my-tool"
3009
+ ],
3010
+ "flags": {
3011
+ "format": {
3012
+ "description": "Output format",
3013
+ "name": "format",
3014
+ "default": "text",
3015
+ "hasDynamicHelp": false,
3016
+ "multiple": false,
3017
+ "options": [
3018
+ "text",
3019
+ "json"
3020
+ ],
3021
+ "type": "option"
2981
3022
  }
2982
3023
  },
2983
3024
  "hasDynamicHelp": false,
2984
3025
  "hiddenAliases": [],
2985
- "id": "migrate:rebake",
3026
+ "id": "plugin:add",
2986
3027
  "pluginAlias": "@memberjunction/cli",
2987
3028
  "pluginName": "@memberjunction/cli",
2988
3029
  "pluginType": "core",
@@ -2992,14 +3033,14 @@
2992
3033
  "relativePath": [
2993
3034
  "dist",
2994
3035
  "commands",
2995
- "migrate",
2996
- "rebake.js"
3036
+ "plugin",
3037
+ "add.js"
2997
3038
  ]
2998
3039
  },
2999
- "migrate:usage": {
3040
+ "plugin:usage": {
3000
3041
  "aliases": [],
3001
3042
  "args": {},
3002
- "description": "Show usage, flags, examples, and runtime hints for every `mj migrate` command.",
3043
+ "description": "Show usage, flags, examples, and runtime hints for every `mj plugin` command.",
3003
3044
  "flags": {
3004
3045
  "format": {
3005
3046
  "description": "Output format. Defaults to text on a terminal and json when stdout is piped.",
@@ -3016,7 +3057,7 @@
3016
3057
  },
3017
3058
  "hasDynamicHelp": false,
3018
3059
  "hiddenAliases": [],
3019
- "id": "migrate:usage",
3060
+ "id": "plugin:usage",
3020
3061
  "pluginAlias": "@memberjunction/cli",
3021
3062
  "pluginName": "@memberjunction/cli",
3022
3063
  "pluginType": "core",
@@ -3026,7 +3067,7 @@
3026
3067
  "relativePath": [
3027
3068
  "dist",
3028
3069
  "commands",
3029
- "migrate",
3070
+ "plugin",
3030
3071
  "usage.js"
3031
3072
  ]
3032
3073
  },
@@ -3721,110 +3762,60 @@
3721
3762
  "usage.js"
3722
3763
  ]
3723
3764
  },
3724
- "test:compare": {
3765
+ "sync:file-reset": {
3725
3766
  "aliases": [],
3726
- "args": {
3727
- "runId1": {
3728
- "description": "First test run ID to compare",
3729
- "name": "runId1",
3730
- "required": false
3731
- },
3732
- "runId2": {
3733
- "description": "Second test run ID to compare",
3734
- "name": "runId2",
3735
- "required": false
3736
- }
3737
- },
3738
- "description": "Compare test runs for regression detection",
3767
+ "args": {},
3768
+ "description": "Reset file metadata sections",
3739
3769
  "examples": [
3740
3770
  "<%= config.bin %> <%= command.id %>",
3741
- "<%= config.bin %> <%= command.id %> --latest",
3742
- "<%= config.bin %> <%= command.id %> <run-id-1> <run-id-2>",
3743
- "<%= config.bin %> <%= command.id %> -v 5.17.0 -v 5.18.0",
3744
- "<%= config.bin %> <%= command.id %> -c abc1234 -c def5678",
3745
- "<%= config.bin %> <%= command.id %> --from-json baseline.json latest.json",
3746
- "<%= config.bin %> <%= command.id %> --latest --format=markdown --output=report.md"
3771
+ "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
3772
+ "<%= config.bin %> <%= command.id %> --sections=\"dependencies,references\"",
3773
+ "<%= config.bin %> <%= command.id %> --all"
3747
3774
  ],
3748
3775
  "flags": {
3749
- "version": {
3750
- "char": "v",
3751
- "description": "Compare runs by version",
3752
- "name": "version",
3776
+ "dir": {
3777
+ "description": "Specific entity directory to reset",
3778
+ "name": "dir",
3753
3779
  "hasDynamicHelp": false,
3754
- "multiple": true,
3780
+ "multiple": false,
3755
3781
  "type": "option"
3756
3782
  },
3757
- "commit": {
3758
- "char": "c",
3759
- "description": "Compare runs by git commit",
3760
- "name": "commit",
3783
+ "sections": {
3784
+ "description": "Comma-separated list of sections to reset (dependencies,references,related,lookup)",
3785
+ "name": "sections",
3761
3786
  "hasDynamicHelp": false,
3762
- "multiple": true,
3787
+ "multiple": false,
3763
3788
  "type": "option"
3764
3789
  },
3765
- "diff-only": {
3766
- "description": "Show only differences",
3767
- "name": "diff-only",
3790
+ "all": {
3791
+ "description": "Reset all metadata sections",
3792
+ "name": "all",
3768
3793
  "allowNo": false,
3769
3794
  "type": "boolean"
3770
3795
  },
3771
- "latest": {
3772
- "char": "l",
3773
- "description": "Compare the two most recent completed suite runs",
3774
- "name": "latest",
3796
+ "dry-run": {
3797
+ "description": "Show what would be reset without actually resetting",
3798
+ "name": "dry-run",
3775
3799
  "allowNo": false,
3776
3800
  "type": "boolean"
3777
3801
  },
3778
- "from-json": {
3779
- "description": "Compare two results.json files directly (no DB). Pass twice: --from-json PREV --from-json CURR",
3780
- "name": "from-json",
3781
- "hasDynamicHelp": false,
3782
- "multiple": true,
3783
- "type": "option"
3784
- },
3785
- "format": {
3786
- "char": "f",
3787
- "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
3788
- "name": "format",
3789
- "hasDynamicHelp": false,
3790
- "multiple": false,
3791
- "options": [
3792
- "text",
3793
- "json",
3794
- "md",
3795
- "human",
3796
- "console",
3797
- "markdown",
3798
- "compact",
3799
- "table"
3800
- ],
3801
- "type": "option"
3802
- },
3803
- "output": {
3804
- "char": "o",
3805
- "description": "Output file path",
3806
- "name": "output",
3807
- "hasDynamicHelp": false,
3808
- "multiple": false,
3809
- "type": "option"
3802
+ "force": {
3803
+ "description": "Skip confirmation prompts",
3804
+ "name": "force",
3805
+ "allowNo": false,
3806
+ "type": "boolean"
3810
3807
  },
3811
3808
  "verbose": {
3812
- "description": "Show detailed information",
3809
+ "char": "v",
3810
+ "description": "Show detailed output",
3813
3811
  "name": "verbose",
3814
3812
  "allowNo": false,
3815
3813
  "type": "boolean"
3816
- },
3817
- "tag": {
3818
- "description": "Filter suite runs by tag (matches against MJTestSuiteRunEntity.Tags). Useful for isolating runs from a specific source environment in an archive MJ. DB mode only — --from-json ignores this flag.",
3819
- "name": "tag",
3820
- "hasDynamicHelp": false,
3821
- "multiple": false,
3822
- "type": "option"
3823
3814
  }
3824
3815
  },
3825
3816
  "hasDynamicHelp": false,
3826
3817
  "hiddenAliases": [],
3827
- "id": "test:compare",
3818
+ "id": "sync:file-reset",
3828
3819
  "pluginAlias": "@memberjunction/cli",
3829
3820
  "pluginName": "@memberjunction/cli",
3830
3821
  "pluginType": "core",
@@ -3834,119 +3825,69 @@
3834
3825
  "relativePath": [
3835
3826
  "dist",
3836
3827
  "commands",
3837
- "test",
3838
- "compare.js"
3828
+ "sync",
3829
+ "file-reset.js"
3839
3830
  ]
3840
3831
  },
3841
- "test:history": {
3832
+ "sync:init": {
3842
3833
  "aliases": [],
3843
3834
  "args": {},
3844
- "description": "View test execution history",
3835
+ "description": "Initialize a directory for metadata synchronization.\n\nPrompts at a terminal; runs unattended when piped, spawned, or in CI. To script it,\npass --setup-entity (and --entity/--dir when setting up \"other\").",
3845
3836
  "examples": [
3846
- "<%= config.bin %> <%= command.id %>",
3847
- "<%= config.bin %> <%= command.id %> --test=<test-id>",
3848
- "<%= config.bin %> <%= command.id %> --suite=<suite-id>",
3849
- "<%= config.bin %> <%= command.id %> --since=\"2024-01-01\"",
3850
- "<%= config.bin %> <%= command.id %> --limit=50"
3851
- ],
3852
- "flags": {
3853
- "test": {
3854
- "char": "t",
3855
- "description": "Filter by test ID",
3856
- "name": "test",
3857
- "hasDynamicHelp": false,
3858
- "multiple": false,
3859
- "type": "option"
3837
+ {
3838
+ "command": "<%= config.bin %> <%= command.id %> --setup-entity=no",
3839
+ "description": "Initialize with no entity directory"
3860
3840
  },
3861
- "recent": {
3862
- "char": "r",
3863
- "description": "Number of recent runs to show",
3864
- "name": "recent",
3865
- "hasDynamicHelp": false,
3866
- "multiple": false,
3867
- "type": "option"
3841
+ {
3842
+ "command": "<%= config.bin %> <%= command.id %> --setup-entity=ai-prompts",
3843
+ "description": "Initialize and set up the AI Prompts directory"
3868
3844
  },
3869
- "from": {
3870
- "description": "Show history from date (YYYY-MM-DD)",
3871
- "name": "from",
3872
- "hasDynamicHelp": false,
3873
- "multiple": false,
3874
- "type": "option"
3845
+ {
3846
+ "command": "<%= config.bin %> <%= command.id %> --setup-entity=other --entity=\"MJ: AI Models\" --dir=ai-models",
3847
+ "description": "Initialize for an arbitrary entity"
3875
3848
  },
3876
- "status": {
3877
- "char": "s",
3878
- "description": "Filter by status",
3879
- "name": "status",
3849
+ {
3850
+ "command": "<%= config.bin %> <%= command.id %> --no-interactive --setup-entity=no",
3851
+ "description": "Never prompt, even at a terminal"
3852
+ }
3853
+ ],
3854
+ "flags": {
3855
+ "setup-entity": {
3856
+ "description": "Which entity directory to set up. Use \"no\" to skip.",
3857
+ "name": "setup-entity",
3880
3858
  "hasDynamicHelp": false,
3881
3859
  "multiple": false,
3860
+ "options": [
3861
+ "ai-prompts",
3862
+ "other",
3863
+ "no"
3864
+ ],
3882
3865
  "type": "option"
3883
3866
  },
3884
- "format": {
3885
- "char": "f",
3886
- "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
3887
- "name": "format",
3867
+ "entity": {
3868
+ "description": "Entity name when --setup-entity=other (e.g. \"MJ: AI Models\").",
3869
+ "name": "entity",
3888
3870
  "hasDynamicHelp": false,
3889
3871
  "multiple": false,
3890
- "options": [
3891
- "text",
3892
- "json",
3893
- "md",
3894
- "human",
3895
- "console",
3896
- "markdown",
3897
- "compact",
3898
- "table"
3899
- ],
3900
3872
  "type": "option"
3901
3873
  },
3902
- "output": {
3903
- "char": "o",
3904
- "description": "Output file path",
3905
- "name": "output",
3874
+ "dir": {
3875
+ "description": "Directory name when --setup-entity=other. Defaults to a slug of --entity.",
3876
+ "name": "dir",
3906
3877
  "hasDynamicHelp": false,
3907
3878
  "multiple": false,
3908
3879
  "type": "option"
3909
3880
  },
3910
- "verbose": {
3911
- "char": "v",
3912
- "description": "Show detailed information",
3913
- "name": "verbose",
3914
- "allowNo": false,
3915
- "type": "boolean"
3916
- }
3917
- },
3918
- "hasDynamicHelp": false,
3919
- "hiddenAliases": [],
3920
- "id": "test:history",
3921
- "pluginAlias": "@memberjunction/cli",
3922
- "pluginName": "@memberjunction/cli",
3923
- "pluginType": "core",
3924
- "strict": true,
3925
- "enableJsonFlag": false,
3926
- "isESM": true,
3927
- "relativePath": [
3928
- "dist",
3929
- "commands",
3930
- "test",
3931
- "history.js"
3932
- ]
3933
- },
3934
- "test": {
3935
- "aliases": [],
3936
- "args": {},
3937
- "description": "MemberJunction Testing Framework - Execute and manage tests",
3938
- "examples": [
3939
- "<%= config.bin %> <%= command.id %> run <test-id>",
3940
- "<%= config.bin %> <%= command.id %> run --name=\"Active Members Count\"",
3941
- "<%= config.bin %> <%= command.id %> suite <suite-id>",
3942
- "<%= config.bin %> <%= command.id %> list",
3943
- "<%= config.bin %> <%= command.id %> list --suites",
3944
- "<%= config.bin %> <%= command.id %> validate --all"
3945
- ],
3946
- "flags": {},
3881
+ "overwrite": {
3882
+ "description": "Overwrite an existing configuration. Without this, an initialized directory is left untouched.",
3883
+ "name": "overwrite",
3884
+ "allowNo": true,
3885
+ "type": "boolean"
3886
+ }
3887
+ },
3947
3888
  "hasDynamicHelp": false,
3948
3889
  "hiddenAliases": [],
3949
- "id": "test",
3890
+ "id": "sync:init",
3950
3891
  "pluginAlias": "@memberjunction/cli",
3951
3892
  "pluginName": "@memberjunction/cli",
3952
3893
  "pluginType": "core",
@@ -3956,145 +3897,238 @@
3956
3897
  "relativePath": [
3957
3898
  "dist",
3958
3899
  "commands",
3959
- "test",
3960
- "index.js"
3900
+ "sync",
3901
+ "init.js"
3961
3902
  ]
3962
3903
  },
3963
- "test:list": {
3904
+ "sync:pull": {
3964
3905
  "aliases": [],
3965
3906
  "args": {},
3966
- "description": "List available tests, suites, and types",
3907
+ "description": "Pull metadata from database to local files",
3967
3908
  "examples": [
3968
- "<%= config.bin %> <%= command.id %>",
3969
- "<%= config.bin %> <%= command.id %> --suites",
3970
- "<%= config.bin %> <%= command.id %> --types",
3971
- "<%= config.bin %> <%= command.id %> --type=agent-eval",
3972
- "<%= config.bin %> <%= command.id %> --tag=smoke",
3973
- "<%= config.bin %> <%= command.id %> --status=active --verbose"
3909
+ "<%= config.bin %> <%= command.id %> --entity=\"MJ: AI Prompts\"",
3910
+ "<%= config.bin %> <%= command.id %> --entity=\"MJ: AI Agents\" --merge-strategy=overwrite",
3911
+ "<%= config.bin %> <%= command.id %> --entity=\"Templates\" --dry-run --verbose"
3974
3912
  ],
3975
3913
  "flags": {
3976
- "suites": {
3977
- "description": "List test suites instead of tests",
3978
- "name": "suites",
3914
+ "format": {
3915
+ "description": "Output format: text (human), json (machine-readable), md (Markdown-fenced). Defaults to text on a terminal and json when stdout is piped.",
3916
+ "name": "format",
3917
+ "hasDynamicHelp": false,
3918
+ "multiple": false,
3919
+ "options": [
3920
+ "text",
3921
+ "json",
3922
+ "md",
3923
+ "human",
3924
+ "console",
3925
+ "markdown"
3926
+ ],
3927
+ "type": "option"
3928
+ },
3929
+ "verbose": {
3930
+ "char": "v",
3931
+ "description": "Show detailed output",
3932
+ "name": "verbose",
3979
3933
  "allowNo": false,
3980
3934
  "type": "boolean"
3981
3935
  },
3982
- "types": {
3983
- "description": "List test types",
3984
- "name": "types",
3936
+ "no-banner": {
3937
+ "description": "Suppress the startup banner and runtime advisory",
3938
+ "name": "no-banner",
3985
3939
  "allowNo": false,
3986
3940
  "type": "boolean"
3987
3941
  },
3988
- "type": {
3989
- "char": "t",
3990
- "description": "Filter by test type",
3991
- "name": "type",
3942
+ "no-app-packages": {
3943
+ "description": "Do not load installed Open App server packages (or the host's generated packages) for this run, so records are written with the generic BaseEntity — no custom Save() logic or lifecycle hooks.",
3944
+ "name": "no-app-packages",
3945
+ "allowNo": false,
3946
+ "type": "boolean"
3947
+ },
3948
+ "interactive": {
3949
+ "description": "Allow interactive prompts. Defaults to on at a terminal and off when piped, spawned, or in CI, so an agent never hangs on a question. Use --no-interactive to force it off.",
3950
+ "name": "interactive",
3951
+ "allowNo": true,
3952
+ "type": "boolean"
3953
+ },
3954
+ "entity": {
3955
+ "description": "Entity name to pull",
3956
+ "name": "entity",
3957
+ "required": true,
3992
3958
  "hasDynamicHelp": false,
3993
3959
  "multiple": false,
3994
3960
  "type": "option"
3995
3961
  },
3996
- "tag": {
3997
- "description": "Filter by tag",
3998
- "name": "tag",
3962
+ "filter": {
3963
+ "description": "Additional filter for pulling specific records",
3964
+ "name": "filter",
3999
3965
  "hasDynamicHelp": false,
4000
3966
  "multiple": false,
4001
3967
  "type": "option"
4002
3968
  },
4003
- "status": {
4004
- "char": "s",
4005
- "description": "Filter by status",
4006
- "name": "status",
3969
+ "dry-run": {
3970
+ "description": "Show what would be pulled without actually pulling",
3971
+ "name": "dry-run",
3972
+ "allowNo": false,
3973
+ "type": "boolean"
3974
+ },
3975
+ "multi-file": {
3976
+ "description": "Create a single file with multiple records (provide filename)",
3977
+ "name": "multi-file",
4007
3978
  "hasDynamicHelp": false,
4008
3979
  "multiple": false,
4009
3980
  "type": "option"
4010
3981
  },
4011
- "format": {
4012
- "char": "f",
4013
- "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
4014
- "name": "format",
3982
+ "no-validate": {
3983
+ "description": "Skip validation before pull",
3984
+ "name": "no-validate",
3985
+ "allowNo": false,
3986
+ "type": "boolean"
3987
+ },
3988
+ "update-existing": {
3989
+ "description": "Update existing records during pull",
3990
+ "name": "update-existing",
3991
+ "allowNo": false,
3992
+ "type": "boolean"
3993
+ },
3994
+ "create-new": {
3995
+ "description": "Create new files for records not found locally",
3996
+ "name": "create-new",
3997
+ "allowNo": false,
3998
+ "type": "boolean"
3999
+ },
4000
+ "backup-before-update": {
4001
+ "description": "Create backups before updating files",
4002
+ "name": "backup-before-update",
4003
+ "allowNo": false,
4004
+ "type": "boolean"
4005
+ },
4006
+ "merge-strategy": {
4007
+ "description": "Merge strategy for updates",
4008
+ "name": "merge-strategy",
4009
+ "default": "merge",
4015
4010
  "hasDynamicHelp": false,
4016
4011
  "multiple": false,
4017
4012
  "options": [
4018
- "text",
4019
- "json",
4020
- "md",
4021
- "human",
4022
- "console",
4023
- "markdown",
4024
- "compact",
4025
- "table"
4013
+ "merge",
4014
+ "overwrite",
4015
+ "skip"
4026
4016
  ],
4027
4017
  "type": "option"
4028
4018
  },
4029
- "output": {
4030
- "char": "o",
4031
- "description": "Output file path",
4032
- "name": "output",
4019
+ "backup-directory": {
4020
+ "description": "Custom backup directory (default: .backups)",
4021
+ "name": "backup-directory",
4033
4022
  "hasDynamicHelp": false,
4034
4023
  "multiple": false,
4035
4024
  "type": "option"
4036
4025
  },
4037
- "verbose": {
4038
- "char": "v",
4039
- "description": "Show detailed information",
4040
- "name": "verbose",
4026
+ "preserve-fields": {
4027
+ "description": "Comma-separated list of fields to preserve during updates",
4028
+ "name": "preserve-fields",
4029
+ "hasDynamicHelp": false,
4030
+ "multiple": true,
4031
+ "type": "option"
4032
+ },
4033
+ "exclude-fields": {
4034
+ "description": "Comma-separated list of fields to exclude from pull",
4035
+ "name": "exclude-fields",
4036
+ "hasDynamicHelp": false,
4037
+ "multiple": true,
4038
+ "type": "option"
4039
+ },
4040
+ "target-dir": {
4041
+ "description": "Specific target directory (overrides auto-discovery)",
4042
+ "name": "target-dir",
4043
+ "hasDynamicHelp": false,
4044
+ "multiple": false,
4045
+ "type": "option"
4046
+ },
4047
+ "incremental": {
4048
+ "description": "Only pull records updated since last successful pull",
4049
+ "name": "incremental",
4041
4050
  "allowNo": false,
4042
4051
  "type": "boolean"
4052
+ },
4053
+ "since": {
4054
+ "description": "Only pull records updated after this ISO 8601 timestamp",
4055
+ "name": "since",
4056
+ "hasDynamicHelp": false,
4057
+ "multiple": false,
4058
+ "type": "option"
4043
4059
  }
4044
4060
  },
4045
4061
  "hasDynamicHelp": false,
4046
4062
  "hiddenAliases": [],
4047
- "id": "test:list",
4063
+ "id": "sync:pull",
4048
4064
  "pluginAlias": "@memberjunction/cli",
4049
4065
  "pluginName": "@memberjunction/cli",
4050
4066
  "pluginType": "core",
4051
4067
  "strict": true,
4052
4068
  "enableJsonFlag": false,
4069
+ "Usage": {
4070
+ "domain": "sync",
4071
+ "command": "sync:pull",
4072
+ "summary": "Pull database records into local metadata files.",
4073
+ "description": "Writes records of --entity into the matching entity directory, creating or updating files per the merge strategy.",
4074
+ "flags": [
4075
+ {
4076
+ "name": "--entity",
4077
+ "type": "string",
4078
+ "description": "Entity name to pull (required)"
4079
+ },
4080
+ {
4081
+ "name": "--filter",
4082
+ "type": "string",
4083
+ "description": "Extra SQL filter for which records to pull"
4084
+ },
4085
+ {
4086
+ "name": "--merge-strategy",
4087
+ "type": "merge|overwrite|skip",
4088
+ "description": "How to reconcile existing files"
4089
+ },
4090
+ {
4091
+ "name": "--dry-run",
4092
+ "type": "boolean",
4093
+ "description": "Report what would be pulled without writing"
4094
+ },
4095
+ {
4096
+ "name": "--format",
4097
+ "type": "text|json|md",
4098
+ "description": "Output format (json for machine-readable result)"
4099
+ }
4100
+ ],
4101
+ "examples": [
4102
+ "mj sync pull --entity=\"MJ: AI Prompts\"",
4103
+ "mj sync pull --entity=\"Actions\" --format=json"
4104
+ ],
4105
+ "runtime": {
4106
+ "class": "variable",
4107
+ "typicalSeconds": 15,
4108
+ "note": "scales with number of records matched for --entity"
4109
+ }
4110
+ },
4053
4111
  "isESM": true,
4054
4112
  "relativePath": [
4055
4113
  "dist",
4056
4114
  "commands",
4057
- "test",
4058
- "list.js"
4115
+ "sync",
4116
+ "pull.js"
4059
4117
  ]
4060
4118
  },
4061
- "test:run": {
4119
+ "sync:push": {
4062
4120
  "aliases": [],
4063
- "args": {
4064
- "testId": {
4065
- "description": "Test ID to execute",
4066
- "name": "testId",
4067
- "required": false
4068
- }
4069
- },
4070
- "description": "Execute a single test by ID or name",
4121
+ "args": {},
4122
+ "description": "Push local file changes to the database",
4071
4123
  "examples": [
4072
- "<%= config.bin %> <%= command.id %> <test-id>",
4073
- "<%= config.bin %> <%= command.id %> --name=\"Active Members Count\"",
4074
- "<%= config.bin %> <%= command.id %> <test-id> --environment=staging",
4075
- "<%= config.bin %> <%= command.id %> <test-id> --format=json --output=results.json",
4076
- "<%= config.bin %> <%= command.id %> <test-id> --dry-run"
4077
- ],
4078
- "flags": {
4079
- "name": {
4080
- "char": "n",
4081
- "description": "Test name to execute",
4082
- "name": "name",
4083
- "hasDynamicHelp": false,
4084
- "multiple": false,
4085
- "type": "option"
4086
- },
4087
- "environment": {
4088
- "char": "e",
4089
- "description": "Environment context (dev, staging, prod)",
4090
- "name": "environment",
4091
- "hasDynamicHelp": false,
4092
- "multiple": false,
4093
- "type": "option"
4094
- },
4124
+ "<%= config.bin %> <%= command.id %>",
4125
+ "<%= config.bin %> <%= command.id %> --dry-run",
4126
+ "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
4127
+ "<%= config.bin %> <%= command.id %> --ci --format=json"
4128
+ ],
4129
+ "flags": {
4095
4130
  "format": {
4096
- "char": "f",
4097
- "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
4131
+ "description": "Output format: text (human), json (machine-readable), md (Markdown-fenced). Defaults to text on a terminal and json when stdout is piped.",
4098
4132
  "name": "format",
4099
4133
  "hasDynamicHelp": false,
4100
4134
  "multiple": false,
@@ -4104,163 +4138,198 @@
4104
4138
  "md",
4105
4139
  "human",
4106
4140
  "console",
4107
- "markdown",
4108
- "compact",
4109
- "table"
4141
+ "markdown"
4110
4142
  ],
4111
4143
  "type": "option"
4112
4144
  },
4113
- "output": {
4114
- "char": "o",
4115
- "description": "Output file path",
4116
- "name": "output",
4145
+ "verbose": {
4146
+ "char": "v",
4147
+ "description": "Show detailed output",
4148
+ "name": "verbose",
4149
+ "allowNo": false,
4150
+ "type": "boolean"
4151
+ },
4152
+ "no-banner": {
4153
+ "description": "Suppress the startup banner and runtime advisory",
4154
+ "name": "no-banner",
4155
+ "allowNo": false,
4156
+ "type": "boolean"
4157
+ },
4158
+ "no-app-packages": {
4159
+ "description": "Do not load installed Open App server packages (or the host's generated packages) for this run, so records are written with the generic BaseEntity — no custom Save() logic or lifecycle hooks.",
4160
+ "name": "no-app-packages",
4161
+ "allowNo": false,
4162
+ "type": "boolean"
4163
+ },
4164
+ "interactive": {
4165
+ "description": "Allow interactive prompts. Defaults to on at a terminal and off when piped, spawned, or in CI, so an agent never hangs on a question. Use --no-interactive to force it off.",
4166
+ "name": "interactive",
4167
+ "allowNo": true,
4168
+ "type": "boolean"
4169
+ },
4170
+ "dir": {
4171
+ "description": "Specific entity directory to push",
4172
+ "name": "dir",
4117
4173
  "hasDynamicHelp": false,
4118
4174
  "multiple": false,
4119
4175
  "type": "option"
4120
4176
  },
4121
4177
  "dry-run": {
4122
- "description": "Validate without executing",
4178
+ "description": "Show what would be pushed without actually pushing",
4123
4179
  "name": "dry-run",
4124
4180
  "allowNo": false,
4125
4181
  "type": "boolean"
4126
4182
  },
4127
- "verbose": {
4128
- "char": "v",
4129
- "description": "Show detailed execution information",
4130
- "name": "verbose",
4183
+ "ci": {
4184
+ "description": "CI mode - no prompts, fail on issues",
4185
+ "name": "ci",
4131
4186
  "allowNo": false,
4132
4187
  "type": "boolean"
4133
4188
  },
4134
- "checks-module": {
4135
- "description": "Module specifier (package name or path) side-effect-imported before the run so its integration check bundles register on the IntegrationCheckRegistry. Durable form: mj.config.cjs `testing.checkModules` (this repo loads '@memberjunction/integration-test-suite' that way).",
4136
- "name": "checks-module",
4189
+ "no-validate": {
4190
+ "description": "Skip validation before push",
4191
+ "name": "no-validate",
4192
+ "allowNo": false,
4193
+ "type": "boolean"
4194
+ },
4195
+ "delete-db-only": {
4196
+ "description": "Delete database-only records that reference records being deleted (prevents FK errors)",
4197
+ "name": "delete-db-only",
4198
+ "allowNo": false,
4199
+ "type": "boolean"
4200
+ },
4201
+ "parallel-batch-size": {
4202
+ "description": "JSON-root graphs to process in parallel (default: 10, not 1)",
4203
+ "name": "parallel-batch-size",
4204
+ "default": 10,
4137
4205
  "hasDynamicHelp": false,
4138
4206
  "multiple": false,
4139
4207
  "type": "option"
4140
4208
  },
4141
- "oracles-module": {
4142
- "description": "Path to a JS/TS module that exports custom IOracle classes or instances. Each export is registered on the engine before the test runs — used by non-MJ adopters to plug app-specific oracle types without modifying TestingFramework.",
4143
- "name": "oracles-module",
4209
+ "include": {
4210
+ "description": "Only process these directories (comma-separated, supports patterns)",
4211
+ "name": "include",
4212
+ "hasDynamicHelp": false,
4213
+ "multiple": false,
4214
+ "type": "option"
4215
+ },
4216
+ "exclude": {
4217
+ "description": "Skip these directories (comma-separated, supports patterns)",
4218
+ "name": "exclude",
4144
4219
  "hasDynamicHelp": false,
4145
4220
  "multiple": false,
4146
4221
  "type": "option"
4222
+ },
4223
+ "incremental": {
4224
+ "description": "Skip unchanged files using stored checksums from last push",
4225
+ "name": "incremental",
4226
+ "allowNo": false,
4227
+ "type": "boolean"
4228
+ },
4229
+ "change-detail": {
4230
+ "description": "Write a detailed per-record change report (primary keys + field diffs) to a file",
4231
+ "name": "change-detail",
4232
+ "allowNo": false,
4233
+ "type": "boolean"
4147
4234
  }
4148
4235
  },
4149
4236
  "hasDynamicHelp": false,
4150
4237
  "hiddenAliases": [],
4151
- "id": "test:run",
4238
+ "id": "sync:push",
4152
4239
  "pluginAlias": "@memberjunction/cli",
4153
4240
  "pluginName": "@memberjunction/cli",
4154
4241
  "pluginType": "core",
4155
4242
  "strict": true,
4156
4243
  "enableJsonFlag": false,
4244
+ "Usage": {
4245
+ "domain": "sync",
4246
+ "command": "sync:push",
4247
+ "summary": "Push local metadata files to the database (upsert).",
4248
+ "description": "Reads entity directories under --dir and creates/updates matching records. Runs validation first unless --no-validate.",
4249
+ "flags": [
4250
+ {
4251
+ "name": "--dir",
4252
+ "type": "string",
4253
+ "description": "Entity directory to push"
4254
+ },
4255
+ {
4256
+ "name": "--dry-run",
4257
+ "type": "boolean",
4258
+ "description": "Report what would change without writing"
4259
+ },
4260
+ {
4261
+ "name": "--ci",
4262
+ "type": "boolean",
4263
+ "description": "No prompts; non-zero exit on error"
4264
+ },
4265
+ {
4266
+ "name": "--no-validate",
4267
+ "type": "boolean",
4268
+ "description": "Skip pre-push validation"
4269
+ },
4270
+ {
4271
+ "name": "--incremental",
4272
+ "type": "boolean",
4273
+ "description": "Skip unchanged files using stored checksums"
4274
+ },
4275
+ {
4276
+ "name": "--format",
4277
+ "type": "text|json|md",
4278
+ "description": "Output format (json for machine-readable result)"
4279
+ }
4280
+ ],
4281
+ "examples": [
4282
+ "mj sync push --dir=ai-agents",
4283
+ "mj sync push --ci --format=json"
4284
+ ],
4285
+ "runtime": {
4286
+ "class": "variable",
4287
+ "typicalSeconds": 20,
4288
+ "note": "scales with number of records in --dir"
4289
+ }
4290
+ },
4157
4291
  "isESM": true,
4158
4292
  "relativePath": [
4159
4293
  "dist",
4160
4294
  "commands",
4161
- "test",
4162
- "run.js"
4295
+ "sync",
4296
+ "push.js"
4163
4297
  ]
4164
4298
  },
4165
- "test:suite": {
4299
+ "sync:status": {
4166
4300
  "aliases": [],
4167
- "args": {
4168
- "suiteId": {
4169
- "description": "Test suite ID to execute",
4170
- "name": "suiteId",
4171
- "required": false
4172
- }
4173
- },
4174
- "description": "Execute a test suite",
4301
+ "args": {},
4302
+ "description": "Show status of local files vs database",
4175
4303
  "examples": [
4176
- "<%= config.bin %> <%= command.id %> <suite-id>",
4177
- "<%= config.bin %> <%= command.id %> --name=\"Agent Quality Suite\"",
4178
- "<%= config.bin %> <%= command.id %> <suite-id> --format=json",
4179
- "<%= config.bin %> <%= command.id %> <suite-id> --output=suite-results.json"
4304
+ "<%= config.bin %> <%= command.id %>",
4305
+ "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
4306
+ "<%= config.bin %> <%= command.id %> --verbose"
4180
4307
  ],
4181
4308
  "flags": {
4182
- "name": {
4183
- "char": "n",
4184
- "description": "Test suite name to execute",
4185
- "name": "name",
4186
- "hasDynamicHelp": false,
4187
- "multiple": false,
4188
- "type": "option"
4189
- },
4190
- "format": {
4191
- "char": "f",
4192
- "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
4193
- "name": "format",
4194
- "hasDynamicHelp": false,
4195
- "multiple": false,
4196
- "options": [
4197
- "text",
4198
- "json",
4199
- "md",
4200
- "human",
4201
- "console",
4202
- "markdown",
4203
- "compact",
4204
- "table"
4205
- ],
4206
- "type": "option"
4207
- },
4208
- "output": {
4209
- "char": "o",
4210
- "description": "Output file path",
4211
- "name": "output",
4309
+ "dir": {
4310
+ "description": "Specific entity directory to check status",
4311
+ "name": "dir",
4212
4312
  "hasDynamicHelp": false,
4213
4313
  "multiple": false,
4214
4314
  "type": "option"
4215
4315
  },
4216
4316
  "verbose": {
4217
4317
  "char": "v",
4218
- "description": "Show detailed execution information",
4318
+ "description": "Show detailed field-level differences",
4219
4319
  "name": "verbose",
4220
4320
  "allowNo": false,
4221
4321
  "type": "boolean"
4222
4322
  },
4223
- "delay": {
4224
- "char": "d",
4225
- "description": "Delay in milliseconds between test executions (avoids Auth0 rate limits)",
4226
- "name": "delay",
4227
- "default": 0,
4228
- "hasDynamicHelp": false,
4229
- "multiple": false,
4230
- "type": "option"
4231
- },
4232
- "parallel": {
4233
- "char": "p",
4234
- "description": "Run tests in parallel with shared browser sessions",
4235
- "name": "parallel",
4236
- "allowNo": false,
4237
- "type": "boolean"
4238
- },
4239
- "max-parallel": {
4240
- "description": "Maximum number of parallel workers (default 4)",
4241
- "name": "max-parallel",
4242
- "default": 4,
4243
- "hasDynamicHelp": false,
4244
- "multiple": false,
4245
- "type": "option"
4246
- },
4247
- "flaky-check": {
4248
- "description": "Run each test N times to detect flakiness (variance > 0.3 or mixed pass/fail = flaky). Recommended: 3 or 5",
4249
- "name": "flaky-check",
4250
- "hasDynamicHelp": false,
4251
- "multiple": false,
4252
- "type": "option"
4253
- },
4254
- "checks-module": {
4255
- "description": "Module specifier (package name or path) side-effect-imported before the run so its integration check bundles register on the IntegrationCheckRegistry. Durable form: mj.config.cjs `testing.checkModules` (this repo loads '@memberjunction/integration-test-suite' that way).",
4256
- "name": "checks-module",
4323
+ "include": {
4324
+ "description": "Only process these directories (comma-separated, supports patterns)",
4325
+ "name": "include",
4257
4326
  "hasDynamicHelp": false,
4258
4327
  "multiple": false,
4259
4328
  "type": "option"
4260
4329
  },
4261
- "oracles-module": {
4262
- "description": "Path to a JS/TS module that exports custom IOracle classes or instances. Each export is registered on the engine before the suite runs — used by non-MJ adopters to plug app-specific oracle types without modifying TestingFramework.",
4263
- "name": "oracles-module",
4330
+ "exclude": {
4331
+ "description": "Skip these directories (comma-separated, supports patterns)",
4332
+ "name": "exclude",
4264
4333
  "hasDynamicHelp": false,
4265
4334
  "multiple": false,
4266
4335
  "type": "option"
@@ -4268,7 +4337,7 @@
4268
4337
  },
4269
4338
  "hasDynamicHelp": false,
4270
4339
  "hiddenAliases": [],
4271
- "id": "test:suite",
4340
+ "id": "sync:status",
4272
4341
  "pluginAlias": "@memberjunction/cli",
4273
4342
  "pluginName": "@memberjunction/cli",
4274
4343
  "pluginType": "core",
@@ -4278,14 +4347,14 @@
4278
4347
  "relativePath": [
4279
4348
  "dist",
4280
4349
  "commands",
4281
- "test",
4282
- "suite.js"
4350
+ "sync",
4351
+ "status.js"
4283
4352
  ]
4284
4353
  },
4285
- "test:usage": {
4354
+ "sync:usage": {
4286
4355
  "aliases": [],
4287
4356
  "args": {},
4288
- "description": "Show usage, flags, examples, and runtime hints for every `mj test` command.",
4357
+ "description": "Show usage, flags, examples, and runtime hints for every `mj sync` command.",
4289
4358
  "flags": {
4290
4359
  "format": {
4291
4360
  "description": "Output format. Defaults to text on a terminal and json when stdout is piped.",
@@ -4302,7 +4371,7 @@
4302
4371
  },
4303
4372
  "hasDynamicHelp": false,
4304
4373
  "hiddenAliases": [],
4305
- "id": "test:usage",
4374
+ "id": "sync:usage",
4306
4375
  "pluginAlias": "@memberjunction/cli",
4307
4376
  "pluginName": "@memberjunction/cli",
4308
4377
  "pluginType": "core",
@@ -4312,86 +4381,52 @@
4312
4381
  "relativePath": [
4313
4382
  "dist",
4314
4383
  "commands",
4315
- "test",
4384
+ "sync",
4316
4385
  "usage.js"
4317
4386
  ]
4318
4387
  },
4319
- "test:validate": {
4388
+ "sync:validate": {
4320
4389
  "aliases": [],
4321
- "args": {
4322
- "testId": {
4323
- "description": "Test ID to validate",
4324
- "name": "testId",
4325
- "required": false
4326
- }
4327
- },
4328
- "description": "Validate test definitions without executing",
4390
+ "args": {},
4391
+ "description": "Validate metadata files",
4329
4392
  "examples": [
4330
- "<%= config.bin %> <%= command.id %> <test-id>",
4331
- "<%= config.bin %> <%= command.id %> --all",
4332
- "<%= config.bin %> <%= command.id %> --type=agent-eval",
4333
- "<%= config.bin %> <%= command.id %> --all --save-report",
4334
- "<%= config.bin %> <%= command.id %> --all --output=validation-report.md"
4393
+ "<%= config.bin %> <%= command.id %>",
4394
+ "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
4395
+ "<%= config.bin %> <%= command.id %> --save-report",
4396
+ "<%= config.bin %> <%= command.id %> --verbose"
4335
4397
  ],
4336
4398
  "flags": {
4337
- "all": {
4338
- "char": "a",
4339
- "description": "Validate all tests",
4340
- "name": "all",
4341
- "allowNo": false,
4342
- "type": "boolean"
4343
- },
4344
- "type": {
4345
- "char": "t",
4346
- "description": "Validate tests by type",
4347
- "name": "type",
4399
+ "dir": {
4400
+ "description": "Specific entity directory to validate",
4401
+ "name": "dir",
4348
4402
  "hasDynamicHelp": false,
4349
4403
  "multiple": false,
4350
4404
  "type": "option"
4351
4405
  },
4406
+ "verbose": {
4407
+ "char": "v",
4408
+ "description": "Show detailed validation output",
4409
+ "name": "verbose",
4410
+ "allowNo": false,
4411
+ "type": "boolean"
4412
+ },
4352
4413
  "save-report": {
4353
- "description": "Save validation report to file",
4414
+ "description": "Save validation report as markdown file",
4354
4415
  "name": "save-report",
4355
4416
  "allowNo": false,
4356
4417
  "type": "boolean"
4357
4418
  },
4358
- "format": {
4359
- "char": "f",
4360
- "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
4361
- "name": "format",
4362
- "hasDynamicHelp": false,
4363
- "multiple": false,
4364
- "options": [
4365
- "text",
4366
- "json",
4367
- "md",
4368
- "human",
4369
- "console",
4370
- "markdown",
4371
- "compact",
4372
- "table"
4373
- ],
4374
- "type": "option"
4375
- },
4376
4419
  "output": {
4377
- "char": "o",
4378
- "description": "Output file path",
4420
+ "description": "Output file path for validation report (default: validation-report.md)",
4379
4421
  "name": "output",
4380
4422
  "hasDynamicHelp": false,
4381
4423
  "multiple": false,
4382
4424
  "type": "option"
4383
- },
4384
- "verbose": {
4385
- "char": "v",
4386
- "description": "Show detailed information",
4387
- "name": "verbose",
4388
- "allowNo": false,
4389
- "type": "boolean"
4390
4425
  }
4391
4426
  },
4392
4427
  "hasDynamicHelp": false,
4393
4428
  "hiddenAliases": [],
4394
- "id": "test:validate",
4429
+ "id": "sync:validate",
4395
4430
  "pluginAlias": "@memberjunction/cli",
4396
4431
  "pluginName": "@memberjunction/cli",
4397
4432
  "pluginType": "core",
@@ -4401,96 +4436,52 @@
4401
4436
  "relativePath": [
4402
4437
  "dist",
4403
4438
  "commands",
4404
- "test",
4439
+ "sync",
4405
4440
  "validate.js"
4406
4441
  ]
4407
4442
  },
4408
- "translate-sql": {
4443
+ "sync:watch": {
4409
4444
  "aliases": [],
4410
4445
  "args": {},
4411
- "description": "Translate SQL fragments between database dialects (SQL Server ↔ PostgreSQL)",
4446
+ "description": "Watch for file changes and sync automatically",
4412
4447
  "examples": [
4413
- "<%= config.bin %> translate-sql --from sqlserver --to postgresql --dry-run",
4414
- "<%= config.bin %> translate-sql --from sqlserver --to postgresql --scope queries",
4415
- "<%= config.bin %> translate-sql --from sqlserver --to postgresql --sql \"SELECT TOP 10 [Name] FROM [Users]\"",
4416
- "<%= config.bin %> translate-sql --from sqlserver --to postgresql --scope all --output ./reports"
4448
+ "<%= config.bin %> <%= command.id %>",
4449
+ "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
4450
+ "<%= config.bin %> <%= command.id %> --debounce=1000",
4451
+ "<%= config.bin %> <%= command.id %> --no-validate"
4417
4452
  ],
4418
4453
  "flags": {
4419
- "from": {
4420
- "description": "Source SQL dialect",
4421
- "name": "from",
4422
- "required": true,
4423
- "hasDynamicHelp": false,
4424
- "multiple": false,
4425
- "options": [
4426
- "sqlserver",
4427
- "postgresql"
4428
- ],
4429
- "type": "option"
4430
- },
4431
- "to": {
4432
- "description": "Target SQL dialect",
4433
- "name": "to",
4434
- "required": true,
4435
- "hasDynamicHelp": false,
4436
- "multiple": false,
4437
- "options": [
4438
- "sqlserver",
4439
- "postgresql"
4440
- ],
4441
- "type": "option"
4442
- },
4443
- "scope": {
4444
- "description": "What to scan for translation",
4445
- "name": "scope",
4446
- "default": "all",
4454
+ "dir": {
4455
+ "description": "Specific entity directory to watch",
4456
+ "name": "dir",
4447
4457
  "hasDynamicHelp": false,
4448
4458
  "multiple": false,
4449
- "options": [
4450
- "queries",
4451
- "views",
4452
- "filters",
4453
- "all"
4454
- ],
4455
4459
  "type": "option"
4456
4460
  },
4457
- "sql": {
4458
- "description": "Translate a single SQL fragment (inline mode)",
4459
- "name": "sql",
4461
+ "debounce": {
4462
+ "description": "Debounce delay in milliseconds (default: 500)",
4463
+ "name": "debounce",
4460
4464
  "hasDynamicHelp": false,
4461
4465
  "multiple": false,
4462
4466
  "type": "option"
4463
4467
  },
4464
- "dry-run": {
4465
- "description": "Show what would be translated without making changes",
4466
- "name": "dry-run",
4467
- "allowNo": false,
4468
- "type": "boolean"
4469
- },
4470
- "review": {
4471
- "description": "Generate review report only (no writes to database)",
4472
- "name": "review",
4468
+ "no-validate": {
4469
+ "description": "Skip validation before sync",
4470
+ "name": "no-validate",
4473
4471
  "allowNo": false,
4474
4472
  "type": "boolean"
4475
4473
  },
4476
- "output": {
4477
- "char": "o",
4478
- "description": "Output directory for the translation report",
4479
- "name": "output",
4480
- "hasDynamicHelp": false,
4481
- "multiple": false,
4482
- "type": "option"
4483
- },
4484
- "force": {
4485
- "description": "Re-translate even if platform variants already exist",
4486
- "name": "force",
4474
+ "verbose": {
4475
+ "char": "v",
4476
+ "description": "Show detailed output",
4477
+ "name": "verbose",
4487
4478
  "allowNo": false,
4488
4479
  "type": "boolean"
4489
4480
  }
4490
4481
  },
4491
4482
  "hasDynamicHelp": false,
4492
4483
  "hiddenAliases": [],
4493
- "id": "translate-sql",
4484
+ "id": "sync:watch",
4494
4485
  "pluginAlias": "@memberjunction/cli",
4495
4486
  "pluginName": "@memberjunction/cli",
4496
4487
  "pluginType": "core",
@@ -4500,31 +4491,114 @@
4500
4491
  "relativePath": [
4501
4492
  "dist",
4502
4493
  "commands",
4503
- "translate-sql",
4504
- "index.js"
4494
+ "sync",
4495
+ "watch.js"
4505
4496
  ]
4506
4497
  },
4507
- "translate-sql:usage": {
4498
+ "test:compare": {
4508
4499
  "aliases": [],
4509
- "args": {},
4510
- "description": "Show usage, flags, examples, and runtime hints for every `mj translate-sql` command.",
4500
+ "args": {
4501
+ "runId1": {
4502
+ "description": "First test run ID to compare",
4503
+ "name": "runId1",
4504
+ "required": false
4505
+ },
4506
+ "runId2": {
4507
+ "description": "Second test run ID to compare",
4508
+ "name": "runId2",
4509
+ "required": false
4510
+ }
4511
+ },
4512
+ "description": "Compare test runs for regression detection",
4513
+ "examples": [
4514
+ "<%= config.bin %> <%= command.id %>",
4515
+ "<%= config.bin %> <%= command.id %> --latest",
4516
+ "<%= config.bin %> <%= command.id %> <run-id-1> <run-id-2>",
4517
+ "<%= config.bin %> <%= command.id %> -v 5.17.0 -v 5.18.0",
4518
+ "<%= config.bin %> <%= command.id %> -c abc1234 -c def5678",
4519
+ "<%= config.bin %> <%= command.id %> --from-json baseline.json latest.json",
4520
+ "<%= config.bin %> <%= command.id %> --latest --format=markdown --output=report.md"
4521
+ ],
4511
4522
  "flags": {
4523
+ "version": {
4524
+ "char": "v",
4525
+ "description": "Compare runs by version",
4526
+ "name": "version",
4527
+ "hasDynamicHelp": false,
4528
+ "multiple": true,
4529
+ "type": "option"
4530
+ },
4531
+ "commit": {
4532
+ "char": "c",
4533
+ "description": "Compare runs by git commit",
4534
+ "name": "commit",
4535
+ "hasDynamicHelp": false,
4536
+ "multiple": true,
4537
+ "type": "option"
4538
+ },
4539
+ "diff-only": {
4540
+ "description": "Show only differences",
4541
+ "name": "diff-only",
4542
+ "allowNo": false,
4543
+ "type": "boolean"
4544
+ },
4545
+ "latest": {
4546
+ "char": "l",
4547
+ "description": "Compare the two most recent completed suite runs",
4548
+ "name": "latest",
4549
+ "allowNo": false,
4550
+ "type": "boolean"
4551
+ },
4552
+ "from-json": {
4553
+ "description": "Compare two results.json files directly (no DB). Pass twice: --from-json PREV --from-json CURR",
4554
+ "name": "from-json",
4555
+ "hasDynamicHelp": false,
4556
+ "multiple": true,
4557
+ "type": "option"
4558
+ },
4512
4559
  "format": {
4513
- "description": "Output format. Defaults to text on a terminal and json when stdout is piped.",
4560
+ "char": "f",
4561
+ "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
4514
4562
  "name": "format",
4515
4563
  "hasDynamicHelp": false,
4516
4564
  "multiple": false,
4517
4565
  "options": [
4518
4566
  "text",
4519
4567
  "json",
4520
- "md"
4568
+ "md",
4569
+ "human",
4570
+ "console",
4571
+ "markdown",
4572
+ "compact",
4573
+ "table"
4521
4574
  ],
4522
4575
  "type": "option"
4576
+ },
4577
+ "output": {
4578
+ "char": "o",
4579
+ "description": "Output file path",
4580
+ "name": "output",
4581
+ "hasDynamicHelp": false,
4582
+ "multiple": false,
4583
+ "type": "option"
4584
+ },
4585
+ "verbose": {
4586
+ "description": "Show detailed information",
4587
+ "name": "verbose",
4588
+ "allowNo": false,
4589
+ "type": "boolean"
4590
+ },
4591
+ "tag": {
4592
+ "description": "Filter suite runs by tag (matches against MJTestSuiteRunEntity.Tags). Useful for isolating runs from a specific source environment in an archive MJ. DB mode only — --from-json ignores this flag.",
4593
+ "name": "tag",
4594
+ "hasDynamicHelp": false,
4595
+ "multiple": false,
4596
+ "type": "option"
4523
4597
  }
4524
4598
  },
4525
4599
  "hasDynamicHelp": false,
4526
4600
  "hiddenAliases": [],
4527
- "id": "translate-sql:usage",
4601
+ "id": "test:compare",
4528
4602
  "pluginAlias": "@memberjunction/cli",
4529
4603
  "pluginName": "@memberjunction/cli",
4530
4604
  "pluginType": "core",
@@ -4534,56 +4608,82 @@
4534
4608
  "relativePath": [
4535
4609
  "dist",
4536
4610
  "commands",
4537
- "translate-sql",
4538
- "usage.js"
4611
+ "test",
4612
+ "compare.js"
4539
4613
  ]
4540
4614
  },
4541
- "sync:file-reset": {
4615
+ "test:history": {
4542
4616
  "aliases": [],
4543
4617
  "args": {},
4544
- "description": "Reset file metadata sections",
4618
+ "description": "View test execution history",
4545
4619
  "examples": [
4546
4620
  "<%= config.bin %> <%= command.id %>",
4547
- "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
4548
- "<%= config.bin %> <%= command.id %> --sections=\"dependencies,references\"",
4549
- "<%= config.bin %> <%= command.id %> --all"
4621
+ "<%= config.bin %> <%= command.id %> --test=<test-id>",
4622
+ "<%= config.bin %> <%= command.id %> --suite=<suite-id>",
4623
+ "<%= config.bin %> <%= command.id %> --since=\"2024-01-01\"",
4624
+ "<%= config.bin %> <%= command.id %> --limit=50"
4550
4625
  ],
4551
4626
  "flags": {
4552
- "dir": {
4553
- "description": "Specific entity directory to reset",
4554
- "name": "dir",
4627
+ "test": {
4628
+ "char": "t",
4629
+ "description": "Filter by test ID",
4630
+ "name": "test",
4555
4631
  "hasDynamicHelp": false,
4556
4632
  "multiple": false,
4557
4633
  "type": "option"
4558
4634
  },
4559
- "sections": {
4560
- "description": "Comma-separated list of sections to reset (dependencies,references,related,lookup)",
4561
- "name": "sections",
4635
+ "recent": {
4636
+ "char": "r",
4637
+ "description": "Number of recent runs to show",
4638
+ "name": "recent",
4562
4639
  "hasDynamicHelp": false,
4563
4640
  "multiple": false,
4564
4641
  "type": "option"
4565
4642
  },
4566
- "all": {
4567
- "description": "Reset all metadata sections",
4568
- "name": "all",
4569
- "allowNo": false,
4570
- "type": "boolean"
4643
+ "from": {
4644
+ "description": "Show history from date (YYYY-MM-DD)",
4645
+ "name": "from",
4646
+ "hasDynamicHelp": false,
4647
+ "multiple": false,
4648
+ "type": "option"
4571
4649
  },
4572
- "dry-run": {
4573
- "description": "Show what would be reset without actually resetting",
4574
- "name": "dry-run",
4575
- "allowNo": false,
4576
- "type": "boolean"
4650
+ "status": {
4651
+ "char": "s",
4652
+ "description": "Filter by status",
4653
+ "name": "status",
4654
+ "hasDynamicHelp": false,
4655
+ "multiple": false,
4656
+ "type": "option"
4577
4657
  },
4578
- "force": {
4579
- "description": "Skip confirmation prompts",
4580
- "name": "force",
4581
- "allowNo": false,
4582
- "type": "boolean"
4658
+ "format": {
4659
+ "char": "f",
4660
+ "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
4661
+ "name": "format",
4662
+ "hasDynamicHelp": false,
4663
+ "multiple": false,
4664
+ "options": [
4665
+ "text",
4666
+ "json",
4667
+ "md",
4668
+ "human",
4669
+ "console",
4670
+ "markdown",
4671
+ "compact",
4672
+ "table"
4673
+ ],
4674
+ "type": "option"
4675
+ },
4676
+ "output": {
4677
+ "char": "o",
4678
+ "description": "Output file path",
4679
+ "name": "output",
4680
+ "hasDynamicHelp": false,
4681
+ "multiple": false,
4682
+ "type": "option"
4583
4683
  },
4584
4684
  "verbose": {
4585
4685
  "char": "v",
4586
- "description": "Show detailed output",
4686
+ "description": "Show detailed information",
4587
4687
  "name": "verbose",
4588
4688
  "allowNo": false,
4589
4689
  "type": "boolean"
@@ -4591,7 +4691,7 @@
4591
4691
  },
4592
4692
  "hasDynamicHelp": false,
4593
4693
  "hiddenAliases": [],
4594
- "id": "sync:file-reset",
4694
+ "id": "test:history",
4595
4695
  "pluginAlias": "@memberjunction/cli",
4596
4696
  "pluginName": "@memberjunction/cli",
4597
4697
  "pluginType": "core",
@@ -4601,69 +4701,124 @@
4601
4701
  "relativePath": [
4602
4702
  "dist",
4603
4703
  "commands",
4604
- "sync",
4605
- "file-reset.js"
4704
+ "test",
4705
+ "history.js"
4606
4706
  ]
4607
4707
  },
4608
- "sync:init": {
4708
+ "test": {
4609
4709
  "aliases": [],
4610
4710
  "args": {},
4611
- "description": "Initialize a directory for metadata synchronization.\n\nPrompts at a terminal; runs unattended when piped, spawned, or in CI. To script it,\npass --setup-entity (and --entity/--dir when setting up \"other\").",
4711
+ "description": "MemberJunction Testing Framework - Execute and manage tests",
4612
4712
  "examples": [
4613
- {
4614
- "command": "<%= config.bin %> <%= command.id %> --setup-entity=no",
4615
- "description": "Initialize with no entity directory"
4713
+ "<%= config.bin %> <%= command.id %> run <test-id>",
4714
+ "<%= config.bin %> <%= command.id %> run --name=\"Active Members Count\"",
4715
+ "<%= config.bin %> <%= command.id %> suite <suite-id>",
4716
+ "<%= config.bin %> <%= command.id %> list",
4717
+ "<%= config.bin %> <%= command.id %> list --suites",
4718
+ "<%= config.bin %> <%= command.id %> validate --all"
4719
+ ],
4720
+ "flags": {},
4721
+ "hasDynamicHelp": false,
4722
+ "hiddenAliases": [],
4723
+ "id": "test",
4724
+ "pluginAlias": "@memberjunction/cli",
4725
+ "pluginName": "@memberjunction/cli",
4726
+ "pluginType": "core",
4727
+ "strict": true,
4728
+ "enableJsonFlag": false,
4729
+ "isESM": true,
4730
+ "relativePath": [
4731
+ "dist",
4732
+ "commands",
4733
+ "test",
4734
+ "index.js"
4735
+ ]
4736
+ },
4737
+ "test:list": {
4738
+ "aliases": [],
4739
+ "args": {},
4740
+ "description": "List available tests, suites, and types",
4741
+ "examples": [
4742
+ "<%= config.bin %> <%= command.id %>",
4743
+ "<%= config.bin %> <%= command.id %> --suites",
4744
+ "<%= config.bin %> <%= command.id %> --types",
4745
+ "<%= config.bin %> <%= command.id %> --type=agent-eval",
4746
+ "<%= config.bin %> <%= command.id %> --tag=smoke",
4747
+ "<%= config.bin %> <%= command.id %> --status=active --verbose"
4748
+ ],
4749
+ "flags": {
4750
+ "suites": {
4751
+ "description": "List test suites instead of tests",
4752
+ "name": "suites",
4753
+ "allowNo": false,
4754
+ "type": "boolean"
4616
4755
  },
4617
- {
4618
- "command": "<%= config.bin %> <%= command.id %> --setup-entity=ai-prompts",
4619
- "description": "Initialize and set up the AI Prompts directory"
4756
+ "types": {
4757
+ "description": "List test types",
4758
+ "name": "types",
4759
+ "allowNo": false,
4760
+ "type": "boolean"
4620
4761
  },
4621
- {
4622
- "command": "<%= config.bin %> <%= command.id %> --setup-entity=other --entity=\"MJ: AI Models\" --dir=ai-models",
4623
- "description": "Initialize for an arbitrary entity"
4762
+ "type": {
4763
+ "char": "t",
4764
+ "description": "Filter by test type",
4765
+ "name": "type",
4766
+ "hasDynamicHelp": false,
4767
+ "multiple": false,
4768
+ "type": "option"
4624
4769
  },
4625
- {
4626
- "command": "<%= config.bin %> <%= command.id %> --no-interactive --setup-entity=no",
4627
- "description": "Never prompt, even at a terminal"
4628
- }
4629
- ],
4630
- "flags": {
4631
- "setup-entity": {
4632
- "description": "Which entity directory to set up. Use \"no\" to skip.",
4633
- "name": "setup-entity",
4770
+ "tag": {
4771
+ "description": "Filter by tag",
4772
+ "name": "tag",
4634
4773
  "hasDynamicHelp": false,
4635
4774
  "multiple": false,
4636
- "options": [
4637
- "ai-prompts",
4638
- "other",
4639
- "no"
4640
- ],
4641
4775
  "type": "option"
4642
4776
  },
4643
- "entity": {
4644
- "description": "Entity name when --setup-entity=other (e.g. \"MJ: AI Models\").",
4645
- "name": "entity",
4777
+ "status": {
4778
+ "char": "s",
4779
+ "description": "Filter by status",
4780
+ "name": "status",
4646
4781
  "hasDynamicHelp": false,
4647
4782
  "multiple": false,
4648
4783
  "type": "option"
4649
4784
  },
4650
- "dir": {
4651
- "description": "Directory name when --setup-entity=other. Defaults to a slug of --entity.",
4652
- "name": "dir",
4785
+ "format": {
4786
+ "char": "f",
4787
+ "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
4788
+ "name": "format",
4653
4789
  "hasDynamicHelp": false,
4654
4790
  "multiple": false,
4791
+ "options": [
4792
+ "text",
4793
+ "json",
4794
+ "md",
4795
+ "human",
4796
+ "console",
4797
+ "markdown",
4798
+ "compact",
4799
+ "table"
4800
+ ],
4655
4801
  "type": "option"
4656
4802
  },
4657
- "overwrite": {
4658
- "description": "Overwrite an existing configuration. Without this, an initialized directory is left untouched.",
4659
- "name": "overwrite",
4660
- "allowNo": true,
4803
+ "output": {
4804
+ "char": "o",
4805
+ "description": "Output file path",
4806
+ "name": "output",
4807
+ "hasDynamicHelp": false,
4808
+ "multiple": false,
4809
+ "type": "option"
4810
+ },
4811
+ "verbose": {
4812
+ "char": "v",
4813
+ "description": "Show detailed information",
4814
+ "name": "verbose",
4815
+ "allowNo": false,
4661
4816
  "type": "boolean"
4662
4817
  }
4663
4818
  },
4664
4819
  "hasDynamicHelp": false,
4665
4820
  "hiddenAliases": [],
4666
- "id": "sync:init",
4821
+ "id": "test:list",
4667
4822
  "pluginAlias": "@memberjunction/cli",
4668
4823
  "pluginName": "@memberjunction/cli",
4669
4824
  "pluginType": "core",
@@ -4673,22 +4828,47 @@
4673
4828
  "relativePath": [
4674
4829
  "dist",
4675
4830
  "commands",
4676
- "sync",
4677
- "init.js"
4831
+ "test",
4832
+ "list.js"
4678
4833
  ]
4679
4834
  },
4680
- "sync:pull": {
4835
+ "test:run": {
4681
4836
  "aliases": [],
4682
- "args": {},
4683
- "description": "Pull metadata from database to local files",
4837
+ "args": {
4838
+ "testId": {
4839
+ "description": "Test ID to execute",
4840
+ "name": "testId",
4841
+ "required": false
4842
+ }
4843
+ },
4844
+ "description": "Execute a single test by ID or name",
4684
4845
  "examples": [
4685
- "<%= config.bin %> <%= command.id %> --entity=\"MJ: AI Prompts\"",
4686
- "<%= config.bin %> <%= command.id %> --entity=\"MJ: AI Agents\" --merge-strategy=overwrite",
4687
- "<%= config.bin %> <%= command.id %> --entity=\"Templates\" --dry-run --verbose"
4846
+ "<%= config.bin %> <%= command.id %> <test-id>",
4847
+ "<%= config.bin %> <%= command.id %> --name=\"Active Members Count\"",
4848
+ "<%= config.bin %> <%= command.id %> <test-id> --environment=staging",
4849
+ "<%= config.bin %> <%= command.id %> <test-id> --format=json --output=results.json",
4850
+ "<%= config.bin %> <%= command.id %> <test-id> --dry-run"
4688
4851
  ],
4689
4852
  "flags": {
4853
+ "name": {
4854
+ "char": "n",
4855
+ "description": "Test name to execute",
4856
+ "name": "name",
4857
+ "hasDynamicHelp": false,
4858
+ "multiple": false,
4859
+ "type": "option"
4860
+ },
4861
+ "environment": {
4862
+ "char": "e",
4863
+ "description": "Environment context (dev, staging, prod)",
4864
+ "name": "environment",
4865
+ "hasDynamicHelp": false,
4866
+ "multiple": false,
4867
+ "type": "option"
4868
+ },
4690
4869
  "format": {
4691
- "description": "Output format: text (human), json (machine-readable), md (Markdown-fenced). Defaults to text on a terminal and json when stdout is piped.",
4870
+ "char": "f",
4871
+ "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
4692
4872
  "name": "format",
4693
4873
  "hasDynamicHelp": false,
4694
4874
  "multiple": false,
@@ -4698,131 +4878,43 @@
4698
4878
  "md",
4699
4879
  "human",
4700
4880
  "console",
4701
- "markdown"
4881
+ "markdown",
4882
+ "compact",
4883
+ "table"
4702
4884
  ],
4703
4885
  "type": "option"
4704
4886
  },
4705
- "verbose": {
4706
- "char": "v",
4707
- "description": "Show detailed output",
4708
- "name": "verbose",
4709
- "allowNo": false,
4710
- "type": "boolean"
4711
- },
4712
- "no-banner": {
4713
- "description": "Suppress the startup banner and runtime advisory",
4714
- "name": "no-banner",
4715
- "allowNo": false,
4716
- "type": "boolean"
4717
- },
4718
- "interactive": {
4719
- "description": "Allow interactive prompts. Defaults to on at a terminal and off when piped, spawned, or in CI, so an agent never hangs on a question. Use --no-interactive to force it off.",
4720
- "name": "interactive",
4721
- "allowNo": true,
4722
- "type": "boolean"
4723
- },
4724
- "entity": {
4725
- "description": "Entity name to pull",
4726
- "name": "entity",
4727
- "required": true,
4728
- "hasDynamicHelp": false,
4729
- "multiple": false,
4730
- "type": "option"
4731
- },
4732
- "filter": {
4733
- "description": "Additional filter for pulling specific records",
4734
- "name": "filter",
4887
+ "output": {
4888
+ "char": "o",
4889
+ "description": "Output file path",
4890
+ "name": "output",
4735
4891
  "hasDynamicHelp": false,
4736
4892
  "multiple": false,
4737
4893
  "type": "option"
4738
4894
  },
4739
4895
  "dry-run": {
4740
- "description": "Show what would be pulled without actually pulling",
4896
+ "description": "Validate without executing",
4741
4897
  "name": "dry-run",
4742
4898
  "allowNo": false,
4743
4899
  "type": "boolean"
4744
4900
  },
4745
- "multi-file": {
4746
- "description": "Create a single file with multiple records (provide filename)",
4747
- "name": "multi-file",
4748
- "hasDynamicHelp": false,
4749
- "multiple": false,
4750
- "type": "option"
4751
- },
4752
- "no-validate": {
4753
- "description": "Skip validation before pull",
4754
- "name": "no-validate",
4755
- "allowNo": false,
4756
- "type": "boolean"
4757
- },
4758
- "update-existing": {
4759
- "description": "Update existing records during pull",
4760
- "name": "update-existing",
4761
- "allowNo": false,
4762
- "type": "boolean"
4763
- },
4764
- "create-new": {
4765
- "description": "Create new files for records not found locally",
4766
- "name": "create-new",
4767
- "allowNo": false,
4768
- "type": "boolean"
4769
- },
4770
- "backup-before-update": {
4771
- "description": "Create backups before updating files",
4772
- "name": "backup-before-update",
4901
+ "verbose": {
4902
+ "char": "v",
4903
+ "description": "Show detailed execution information",
4904
+ "name": "verbose",
4773
4905
  "allowNo": false,
4774
4906
  "type": "boolean"
4775
4907
  },
4776
- "merge-strategy": {
4777
- "description": "Merge strategy for updates",
4778
- "name": "merge-strategy",
4779
- "default": "merge",
4780
- "hasDynamicHelp": false,
4781
- "multiple": false,
4782
- "options": [
4783
- "merge",
4784
- "overwrite",
4785
- "skip"
4786
- ],
4787
- "type": "option"
4788
- },
4789
- "backup-directory": {
4790
- "description": "Custom backup directory (default: .backups)",
4791
- "name": "backup-directory",
4792
- "hasDynamicHelp": false,
4793
- "multiple": false,
4794
- "type": "option"
4795
- },
4796
- "preserve-fields": {
4797
- "description": "Comma-separated list of fields to preserve during updates",
4798
- "name": "preserve-fields",
4799
- "hasDynamicHelp": false,
4800
- "multiple": true,
4801
- "type": "option"
4802
- },
4803
- "exclude-fields": {
4804
- "description": "Comma-separated list of fields to exclude from pull",
4805
- "name": "exclude-fields",
4806
- "hasDynamicHelp": false,
4807
- "multiple": true,
4808
- "type": "option"
4809
- },
4810
- "target-dir": {
4811
- "description": "Specific target directory (overrides auto-discovery)",
4812
- "name": "target-dir",
4908
+ "checks-module": {
4909
+ "description": "Module specifier (package name or path) side-effect-imported before the run so its integration check bundles register on the IntegrationCheckRegistry. Durable form: mj.config.cjs `testing.checkModules` (this repo loads '@memberjunction/integration-test-suite' that way).",
4910
+ "name": "checks-module",
4813
4911
  "hasDynamicHelp": false,
4814
4912
  "multiple": false,
4815
4913
  "type": "option"
4816
4914
  },
4817
- "incremental": {
4818
- "description": "Only pull records updated since last successful pull",
4819
- "name": "incremental",
4820
- "allowNo": false,
4821
- "type": "boolean"
4822
- },
4823
- "since": {
4824
- "description": "Only pull records updated after this ISO 8601 timestamp",
4825
- "name": "since",
4915
+ "oracles-module": {
4916
+ "description": "Path to a JS/TS module that exports custom IOracle classes or instances. Each export is registered on the engine before the test runs — used by non-MJ adopters to plug app-specific oracle types without modifying TestingFramework.",
4917
+ "name": "oracles-module",
4826
4918
  "hasDynamicHelp": false,
4827
4919
  "multiple": false,
4828
4920
  "type": "option"
@@ -4830,75 +4922,48 @@
4830
4922
  },
4831
4923
  "hasDynamicHelp": false,
4832
4924
  "hiddenAliases": [],
4833
- "id": "sync:pull",
4925
+ "id": "test:run",
4834
4926
  "pluginAlias": "@memberjunction/cli",
4835
4927
  "pluginName": "@memberjunction/cli",
4836
4928
  "pluginType": "core",
4837
4929
  "strict": true,
4838
4930
  "enableJsonFlag": false,
4839
- "Usage": {
4840
- "domain": "sync",
4841
- "command": "sync:pull",
4842
- "summary": "Pull database records into local metadata files.",
4843
- "description": "Writes records of --entity into the matching entity directory, creating or updating files per the merge strategy.",
4844
- "flags": [
4845
- {
4846
- "name": "--entity",
4847
- "type": "string",
4848
- "description": "Entity name to pull (required)"
4849
- },
4850
- {
4851
- "name": "--filter",
4852
- "type": "string",
4853
- "description": "Extra SQL filter for which records to pull"
4854
- },
4855
- {
4856
- "name": "--merge-strategy",
4857
- "type": "merge|overwrite|skip",
4858
- "description": "How to reconcile existing files"
4859
- },
4860
- {
4861
- "name": "--dry-run",
4862
- "type": "boolean",
4863
- "description": "Report what would be pulled without writing"
4864
- },
4865
- {
4866
- "name": "--format",
4867
- "type": "text|json|md",
4868
- "description": "Output format (json for machine-readable result)"
4869
- }
4870
- ],
4871
- "examples": [
4872
- "mj sync pull --entity=\"MJ: AI Prompts\"",
4873
- "mj sync pull --entity=\"Actions\" --format=json"
4874
- ],
4875
- "runtime": {
4876
- "class": "variable",
4877
- "typicalSeconds": 15,
4878
- "note": "scales with number of records matched for --entity"
4879
- }
4880
- },
4881
4931
  "isESM": true,
4882
4932
  "relativePath": [
4883
4933
  "dist",
4884
4934
  "commands",
4885
- "sync",
4886
- "pull.js"
4935
+ "test",
4936
+ "run.js"
4887
4937
  ]
4888
4938
  },
4889
- "sync:push": {
4939
+ "test:suite": {
4890
4940
  "aliases": [],
4891
- "args": {},
4892
- "description": "Push local file changes to the database",
4941
+ "args": {
4942
+ "suiteId": {
4943
+ "description": "Test suite ID to execute",
4944
+ "name": "suiteId",
4945
+ "required": false
4946
+ }
4947
+ },
4948
+ "description": "Execute a test suite",
4893
4949
  "examples": [
4894
- "<%= config.bin %> <%= command.id %>",
4895
- "<%= config.bin %> <%= command.id %> --dry-run",
4896
- "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
4897
- "<%= config.bin %> <%= command.id %> --ci --format=json"
4950
+ "<%= config.bin %> <%= command.id %> <suite-id>",
4951
+ "<%= config.bin %> <%= command.id %> --name=\"Agent Quality Suite\"",
4952
+ "<%= config.bin %> <%= command.id %> <suite-id> --format=json",
4953
+ "<%= config.bin %> <%= command.id %> <suite-id> --output=suite-results.json"
4898
4954
  ],
4899
4955
  "flags": {
4956
+ "name": {
4957
+ "char": "n",
4958
+ "description": "Test suite name to execute",
4959
+ "name": "name",
4960
+ "hasDynamicHelp": false,
4961
+ "multiple": false,
4962
+ "type": "option"
4963
+ },
4900
4964
  "format": {
4901
- "description": "Output format: text (human), json (machine-readable), md (Markdown-fenced). Defaults to text on a terminal and json when stdout is piped.",
4965
+ "char": "f",
4966
+ "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
4902
4967
  "name": "format",
4903
4968
  "hasDynamicHelp": false,
4904
4969
  "multiple": false,
@@ -4908,200 +4973,199 @@
4908
4973
  "md",
4909
4974
  "human",
4910
4975
  "console",
4911
- "markdown"
4976
+ "markdown",
4977
+ "compact",
4978
+ "table"
4912
4979
  ],
4913
4980
  "type": "option"
4914
4981
  },
4915
- "verbose": {
4916
- "char": "v",
4917
- "description": "Show detailed output",
4918
- "name": "verbose",
4919
- "allowNo": false,
4920
- "type": "boolean"
4921
- },
4922
- "no-banner": {
4923
- "description": "Suppress the startup banner and runtime advisory",
4924
- "name": "no-banner",
4925
- "allowNo": false,
4926
- "type": "boolean"
4927
- },
4928
- "interactive": {
4929
- "description": "Allow interactive prompts. Defaults to on at a terminal and off when piped, spawned, or in CI, so an agent never hangs on a question. Use --no-interactive to force it off.",
4930
- "name": "interactive",
4931
- "allowNo": true,
4932
- "type": "boolean"
4933
- },
4934
- "dir": {
4935
- "description": "Specific entity directory to push",
4936
- "name": "dir",
4937
- "hasDynamicHelp": false,
4938
- "multiple": false,
4939
- "type": "option"
4940
- },
4941
- "dry-run": {
4942
- "description": "Show what would be pushed without actually pushing",
4943
- "name": "dry-run",
4944
- "allowNo": false,
4945
- "type": "boolean"
4946
- },
4947
- "ci": {
4948
- "description": "CI mode - no prompts, fail on issues",
4949
- "name": "ci",
4950
- "allowNo": false,
4951
- "type": "boolean"
4982
+ "output": {
4983
+ "char": "o",
4984
+ "description": "Output file path",
4985
+ "name": "output",
4986
+ "hasDynamicHelp": false,
4987
+ "multiple": false,
4988
+ "type": "option"
4952
4989
  },
4953
- "no-validate": {
4954
- "description": "Skip validation before push",
4955
- "name": "no-validate",
4990
+ "verbose": {
4991
+ "char": "v",
4992
+ "description": "Show detailed execution information",
4993
+ "name": "verbose",
4956
4994
  "allowNo": false,
4957
4995
  "type": "boolean"
4958
4996
  },
4959
- "delete-db-only": {
4960
- "description": "Delete database-only records that reference records being deleted (prevents FK errors)",
4961
- "name": "delete-db-only",
4997
+ "delay": {
4998
+ "char": "d",
4999
+ "description": "Delay in milliseconds between test executions (avoids Auth0 rate limits)",
5000
+ "name": "delay",
5001
+ "default": 0,
5002
+ "hasDynamicHelp": false,
5003
+ "multiple": false,
5004
+ "type": "option"
5005
+ },
5006
+ "parallel": {
5007
+ "char": "p",
5008
+ "description": "Run tests in parallel with shared browser sessions",
5009
+ "name": "parallel",
4962
5010
  "allowNo": false,
4963
5011
  "type": "boolean"
4964
5012
  },
4965
- "parallel-batch-size": {
4966
- "description": "Number of records to process in parallel (default: 10)",
4967
- "name": "parallel-batch-size",
4968
- "default": 10,
5013
+ "max-parallel": {
5014
+ "description": "Maximum number of parallel workers (default 4)",
5015
+ "name": "max-parallel",
5016
+ "default": 4,
4969
5017
  "hasDynamicHelp": false,
4970
5018
  "multiple": false,
4971
5019
  "type": "option"
4972
5020
  },
4973
- "include": {
4974
- "description": "Only process these directories (comma-separated, supports patterns)",
4975
- "name": "include",
5021
+ "flaky-check": {
5022
+ "description": "Run each test N times to detect flakiness (variance > 0.3 or mixed pass/fail = flaky). Recommended: 3 or 5",
5023
+ "name": "flaky-check",
4976
5024
  "hasDynamicHelp": false,
4977
5025
  "multiple": false,
4978
5026
  "type": "option"
4979
5027
  },
4980
- "exclude": {
4981
- "description": "Skip these directories (comma-separated, supports patterns)",
4982
- "name": "exclude",
5028
+ "checks-module": {
5029
+ "description": "Module specifier (package name or path) side-effect-imported before the run so its integration check bundles register on the IntegrationCheckRegistry. Durable form: mj.config.cjs `testing.checkModules` (this repo loads '@memberjunction/integration-test-suite' that way).",
5030
+ "name": "checks-module",
4983
5031
  "hasDynamicHelp": false,
4984
5032
  "multiple": false,
4985
5033
  "type": "option"
4986
5034
  },
4987
- "incremental": {
4988
- "description": "Skip unchanged files using stored checksums from last push",
4989
- "name": "incremental",
4990
- "allowNo": false,
4991
- "type": "boolean"
4992
- },
4993
- "change-detail": {
4994
- "description": "Write a detailed per-record change report (primary keys + field diffs) to a file",
4995
- "name": "change-detail",
4996
- "allowNo": false,
4997
- "type": "boolean"
5035
+ "oracles-module": {
5036
+ "description": "Path to a JS/TS module that exports custom IOracle classes or instances. Each export is registered on the engine before the suite runs — used by non-MJ adopters to plug app-specific oracle types without modifying TestingFramework.",
5037
+ "name": "oracles-module",
5038
+ "hasDynamicHelp": false,
5039
+ "multiple": false,
5040
+ "type": "option"
4998
5041
  }
4999
5042
  },
5000
5043
  "hasDynamicHelp": false,
5001
5044
  "hiddenAliases": [],
5002
- "id": "sync:push",
5045
+ "id": "test:suite",
5003
5046
  "pluginAlias": "@memberjunction/cli",
5004
5047
  "pluginName": "@memberjunction/cli",
5005
5048
  "pluginType": "core",
5006
5049
  "strict": true,
5007
5050
  "enableJsonFlag": false,
5008
- "Usage": {
5009
- "domain": "sync",
5010
- "command": "sync:push",
5011
- "summary": "Push local metadata files to the database (upsert).",
5012
- "description": "Reads entity directories under --dir and creates/updates matching records. Runs validation first unless --no-validate.",
5013
- "flags": [
5014
- {
5015
- "name": "--dir",
5016
- "type": "string",
5017
- "description": "Entity directory to push"
5018
- },
5019
- {
5020
- "name": "--dry-run",
5021
- "type": "boolean",
5022
- "description": "Report what would change without writing"
5023
- },
5024
- {
5025
- "name": "--ci",
5026
- "type": "boolean",
5027
- "description": "No prompts; non-zero exit on error"
5028
- },
5029
- {
5030
- "name": "--no-validate",
5031
- "type": "boolean",
5032
- "description": "Skip pre-push validation"
5033
- },
5034
- {
5035
- "name": "--incremental",
5036
- "type": "boolean",
5037
- "description": "Skip unchanged files using stored checksums"
5038
- },
5039
- {
5040
- "name": "--format",
5041
- "type": "text|json|md",
5042
- "description": "Output format (json for machine-readable result)"
5043
- }
5044
- ],
5045
- "examples": [
5046
- "mj sync push --dir=ai-agents",
5047
- "mj sync push --ci --format=json"
5048
- ],
5049
- "runtime": {
5050
- "class": "variable",
5051
- "typicalSeconds": 20,
5052
- "note": "scales with number of records in --dir"
5051
+ "isESM": true,
5052
+ "relativePath": [
5053
+ "dist",
5054
+ "commands",
5055
+ "test",
5056
+ "suite.js"
5057
+ ]
5058
+ },
5059
+ "test:usage": {
5060
+ "aliases": [],
5061
+ "args": {},
5062
+ "description": "Show usage, flags, examples, and runtime hints for every `mj test` command.",
5063
+ "flags": {
5064
+ "format": {
5065
+ "description": "Output format. Defaults to text on a terminal and json when stdout is piped.",
5066
+ "name": "format",
5067
+ "hasDynamicHelp": false,
5068
+ "multiple": false,
5069
+ "options": [
5070
+ "text",
5071
+ "json",
5072
+ "md"
5073
+ ],
5074
+ "type": "option"
5053
5075
  }
5054
5076
  },
5077
+ "hasDynamicHelp": false,
5078
+ "hiddenAliases": [],
5079
+ "id": "test:usage",
5080
+ "pluginAlias": "@memberjunction/cli",
5081
+ "pluginName": "@memberjunction/cli",
5082
+ "pluginType": "core",
5083
+ "strict": true,
5084
+ "enableJsonFlag": false,
5055
5085
  "isESM": true,
5056
5086
  "relativePath": [
5057
5087
  "dist",
5058
5088
  "commands",
5059
- "sync",
5060
- "push.js"
5089
+ "test",
5090
+ "usage.js"
5061
5091
  ]
5062
5092
  },
5063
- "sync:status": {
5093
+ "test:validate": {
5064
5094
  "aliases": [],
5065
- "args": {},
5066
- "description": "Show status of local files vs database",
5095
+ "args": {
5096
+ "testId": {
5097
+ "description": "Test ID to validate",
5098
+ "name": "testId",
5099
+ "required": false
5100
+ }
5101
+ },
5102
+ "description": "Validate test definitions without executing",
5067
5103
  "examples": [
5068
- "<%= config.bin %> <%= command.id %>",
5069
- "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
5070
- "<%= config.bin %> <%= command.id %> --verbose"
5104
+ "<%= config.bin %> <%= command.id %> <test-id>",
5105
+ "<%= config.bin %> <%= command.id %> --all",
5106
+ "<%= config.bin %> <%= command.id %> --type=agent-eval",
5107
+ "<%= config.bin %> <%= command.id %> --all --save-report",
5108
+ "<%= config.bin %> <%= command.id %> --all --output=validation-report.md"
5071
5109
  ],
5072
5110
  "flags": {
5073
- "dir": {
5074
- "description": "Specific entity directory to check status",
5075
- "name": "dir",
5111
+ "all": {
5112
+ "char": "a",
5113
+ "description": "Validate all tests",
5114
+ "name": "all",
5115
+ "allowNo": false,
5116
+ "type": "boolean"
5117
+ },
5118
+ "type": {
5119
+ "char": "t",
5120
+ "description": "Validate tests by type",
5121
+ "name": "type",
5076
5122
  "hasDynamicHelp": false,
5077
5123
  "multiple": false,
5078
5124
  "type": "option"
5079
5125
  },
5080
- "verbose": {
5081
- "char": "v",
5082
- "description": "Show detailed field-level differences",
5083
- "name": "verbose",
5126
+ "save-report": {
5127
+ "description": "Save validation report to file",
5128
+ "name": "save-report",
5084
5129
  "allowNo": false,
5085
5130
  "type": "boolean"
5086
5131
  },
5087
- "include": {
5088
- "description": "Only process these directories (comma-separated, supports patterns)",
5089
- "name": "include",
5132
+ "format": {
5133
+ "char": "f",
5134
+ "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
5135
+ "name": "format",
5090
5136
  "hasDynamicHelp": false,
5091
5137
  "multiple": false,
5138
+ "options": [
5139
+ "text",
5140
+ "json",
5141
+ "md",
5142
+ "human",
5143
+ "console",
5144
+ "markdown",
5145
+ "compact",
5146
+ "table"
5147
+ ],
5092
5148
  "type": "option"
5093
5149
  },
5094
- "exclude": {
5095
- "description": "Skip these directories (comma-separated, supports patterns)",
5096
- "name": "exclude",
5150
+ "output": {
5151
+ "char": "o",
5152
+ "description": "Output file path",
5153
+ "name": "output",
5097
5154
  "hasDynamicHelp": false,
5098
5155
  "multiple": false,
5099
5156
  "type": "option"
5157
+ },
5158
+ "verbose": {
5159
+ "char": "v",
5160
+ "description": "Show detailed information",
5161
+ "name": "verbose",
5162
+ "allowNo": false,
5163
+ "type": "boolean"
5100
5164
  }
5101
5165
  },
5102
5166
  "hasDynamicHelp": false,
5103
5167
  "hiddenAliases": [],
5104
- "id": "sync:status",
5168
+ "id": "test:validate",
5105
5169
  "pluginAlias": "@memberjunction/cli",
5106
5170
  "pluginName": "@memberjunction/cli",
5107
5171
  "pluginType": "core",
@@ -5111,86 +5175,96 @@
5111
5175
  "relativePath": [
5112
5176
  "dist",
5113
5177
  "commands",
5114
- "sync",
5115
- "status.js"
5178
+ "test",
5179
+ "validate.js"
5116
5180
  ]
5117
5181
  },
5118
- "sync:usage": {
5182
+ "translate-sql": {
5119
5183
  "aliases": [],
5120
5184
  "args": {},
5121
- "description": "Show usage, flags, examples, and runtime hints for every `mj sync` command.",
5185
+ "description": "Translate SQL fragments between database dialects (SQL Server PostgreSQL)",
5186
+ "examples": [
5187
+ "<%= config.bin %> translate-sql --from sqlserver --to postgresql --dry-run",
5188
+ "<%= config.bin %> translate-sql --from sqlserver --to postgresql --scope queries",
5189
+ "<%= config.bin %> translate-sql --from sqlserver --to postgresql --sql \"SELECT TOP 10 [Name] FROM [Users]\"",
5190
+ "<%= config.bin %> translate-sql --from sqlserver --to postgresql --scope all --output ./reports"
5191
+ ],
5122
5192
  "flags": {
5123
- "format": {
5124
- "description": "Output format. Defaults to text on a terminal and json when stdout is piped.",
5125
- "name": "format",
5193
+ "from": {
5194
+ "description": "Source SQL dialect",
5195
+ "name": "from",
5196
+ "required": true,
5197
+ "hasDynamicHelp": false,
5198
+ "multiple": false,
5199
+ "options": [
5200
+ "sqlserver",
5201
+ "postgresql"
5202
+ ],
5203
+ "type": "option"
5204
+ },
5205
+ "to": {
5206
+ "description": "Target SQL dialect",
5207
+ "name": "to",
5208
+ "required": true,
5209
+ "hasDynamicHelp": false,
5210
+ "multiple": false,
5211
+ "options": [
5212
+ "sqlserver",
5213
+ "postgresql"
5214
+ ],
5215
+ "type": "option"
5216
+ },
5217
+ "scope": {
5218
+ "description": "What to scan for translation",
5219
+ "name": "scope",
5220
+ "default": "all",
5126
5221
  "hasDynamicHelp": false,
5127
5222
  "multiple": false,
5128
5223
  "options": [
5129
- "text",
5130
- "json",
5131
- "md"
5224
+ "queries",
5225
+ "views",
5226
+ "filters",
5227
+ "all"
5132
5228
  ],
5133
5229
  "type": "option"
5134
- }
5135
- },
5136
- "hasDynamicHelp": false,
5137
- "hiddenAliases": [],
5138
- "id": "sync:usage",
5139
- "pluginAlias": "@memberjunction/cli",
5140
- "pluginName": "@memberjunction/cli",
5141
- "pluginType": "core",
5142
- "strict": true,
5143
- "enableJsonFlag": false,
5144
- "isESM": true,
5145
- "relativePath": [
5146
- "dist",
5147
- "commands",
5148
- "sync",
5149
- "usage.js"
5150
- ]
5151
- },
5152
- "sync:validate": {
5153
- "aliases": [],
5154
- "args": {},
5155
- "description": "Validate metadata files",
5156
- "examples": [
5157
- "<%= config.bin %> <%= command.id %>",
5158
- "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
5159
- "<%= config.bin %> <%= command.id %> --save-report",
5160
- "<%= config.bin %> <%= command.id %> --verbose"
5161
- ],
5162
- "flags": {
5163
- "dir": {
5164
- "description": "Specific entity directory to validate",
5165
- "name": "dir",
5230
+ },
5231
+ "sql": {
5232
+ "description": "Translate a single SQL fragment (inline mode)",
5233
+ "name": "sql",
5166
5234
  "hasDynamicHelp": false,
5167
5235
  "multiple": false,
5168
5236
  "type": "option"
5169
5237
  },
5170
- "verbose": {
5171
- "char": "v",
5172
- "description": "Show detailed validation output",
5173
- "name": "verbose",
5238
+ "dry-run": {
5239
+ "description": "Show what would be translated without making changes",
5240
+ "name": "dry-run",
5174
5241
  "allowNo": false,
5175
5242
  "type": "boolean"
5176
5243
  },
5177
- "save-report": {
5178
- "description": "Save validation report as markdown file",
5179
- "name": "save-report",
5244
+ "review": {
5245
+ "description": "Generate review report only (no writes to database)",
5246
+ "name": "review",
5180
5247
  "allowNo": false,
5181
5248
  "type": "boolean"
5182
5249
  },
5183
5250
  "output": {
5184
- "description": "Output file path for validation report (default: validation-report.md)",
5251
+ "char": "o",
5252
+ "description": "Output directory for the translation report",
5185
5253
  "name": "output",
5186
5254
  "hasDynamicHelp": false,
5187
5255
  "multiple": false,
5188
5256
  "type": "option"
5257
+ },
5258
+ "force": {
5259
+ "description": "Re-translate even if platform variants already exist",
5260
+ "name": "force",
5261
+ "allowNo": false,
5262
+ "type": "boolean"
5189
5263
  }
5190
5264
  },
5191
5265
  "hasDynamicHelp": false,
5192
5266
  "hiddenAliases": [],
5193
- "id": "sync:validate",
5267
+ "id": "translate-sql",
5194
5268
  "pluginAlias": "@memberjunction/cli",
5195
5269
  "pluginName": "@memberjunction/cli",
5196
5270
  "pluginType": "core",
@@ -5200,52 +5274,31 @@
5200
5274
  "relativePath": [
5201
5275
  "dist",
5202
5276
  "commands",
5203
- "sync",
5204
- "validate.js"
5277
+ "translate-sql",
5278
+ "index.js"
5205
5279
  ]
5206
5280
  },
5207
- "sync:watch": {
5281
+ "translate-sql:usage": {
5208
5282
  "aliases": [],
5209
5283
  "args": {},
5210
- "description": "Watch for file changes and sync automatically",
5211
- "examples": [
5212
- "<%= config.bin %> <%= command.id %>",
5213
- "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
5214
- "<%= config.bin %> <%= command.id %> --debounce=1000",
5215
- "<%= config.bin %> <%= command.id %> --no-validate"
5216
- ],
5284
+ "description": "Show usage, flags, examples, and runtime hints for every `mj translate-sql` command.",
5217
5285
  "flags": {
5218
- "dir": {
5219
- "description": "Specific entity directory to watch",
5220
- "name": "dir",
5221
- "hasDynamicHelp": false,
5222
- "multiple": false,
5223
- "type": "option"
5224
- },
5225
- "debounce": {
5226
- "description": "Debounce delay in milliseconds (default: 500)",
5227
- "name": "debounce",
5286
+ "format": {
5287
+ "description": "Output format. Defaults to text on a terminal and json when stdout is piped.",
5288
+ "name": "format",
5228
5289
  "hasDynamicHelp": false,
5229
5290
  "multiple": false,
5291
+ "options": [
5292
+ "text",
5293
+ "json",
5294
+ "md"
5295
+ ],
5230
5296
  "type": "option"
5231
- },
5232
- "no-validate": {
5233
- "description": "Skip validation before sync",
5234
- "name": "no-validate",
5235
- "allowNo": false,
5236
- "type": "boolean"
5237
- },
5238
- "verbose": {
5239
- "char": "v",
5240
- "description": "Show detailed output",
5241
- "name": "verbose",
5242
- "allowNo": false,
5243
- "type": "boolean"
5244
5297
  }
5245
5298
  },
5246
5299
  "hasDynamicHelp": false,
5247
5300
  "hiddenAliases": [],
5248
- "id": "sync:watch",
5301
+ "id": "translate-sql:usage",
5249
5302
  "pluginAlias": "@memberjunction/cli",
5250
5303
  "pluginName": "@memberjunction/cli",
5251
5304
  "pluginType": "core",
@@ -5255,8 +5308,8 @@
5255
5308
  "relativePath": [
5256
5309
  "dist",
5257
5310
  "commands",
5258
- "sync",
5259
- "watch.js"
5311
+ "translate-sql",
5312
+ "usage.js"
5260
5313
  ]
5261
5314
  },
5262
5315
  "update:claude": {
@@ -5408,16 +5461,172 @@
5408
5461
  "hasDynamicHelp": false,
5409
5462
  "multiple": false,
5410
5463
  "options": [
5411
- "text",
5464
+ "text",
5465
+ "json",
5466
+ "md"
5467
+ ],
5468
+ "type": "option"
5469
+ }
5470
+ },
5471
+ "hasDynamicHelp": false,
5472
+ "hiddenAliases": [],
5473
+ "id": "update:usage",
5474
+ "pluginAlias": "@memberjunction/cli",
5475
+ "pluginName": "@memberjunction/cli",
5476
+ "pluginType": "core",
5477
+ "strict": true,
5478
+ "enableJsonFlag": false,
5479
+ "isESM": true,
5480
+ "relativePath": [
5481
+ "dist",
5482
+ "commands",
5483
+ "update",
5484
+ "usage.js"
5485
+ ]
5486
+ },
5487
+ "ai:actions:list": {
5488
+ "aliases": [],
5489
+ "args": {},
5490
+ "description": "List available AI actions",
5491
+ "examples": [
5492
+ "<%= config.bin %> <%= command.id %>",
5493
+ "<%= config.bin %> <%= command.id %> --output=table",
5494
+ "<%= config.bin %> <%= command.id %> --output=json"
5495
+ ],
5496
+ "flags": {
5497
+ "format": {
5498
+ "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
5499
+ "name": "format",
5500
+ "hasDynamicHelp": false,
5501
+ "multiple": false,
5502
+ "options": [
5503
+ "text",
5504
+ "json",
5505
+ "md",
5506
+ "human",
5507
+ "console",
5508
+ "markdown",
5509
+ "compact",
5510
+ "table"
5511
+ ],
5512
+ "type": "option"
5513
+ },
5514
+ "output": {
5515
+ "char": "o",
5516
+ "description": "Output format (legacy alias for --format in the 'mj ai' family; elsewhere -o is an output FILE path). Prefer --format.",
5517
+ "name": "output",
5518
+ "default": "compact",
5519
+ "hasDynamicHelp": false,
5520
+ "multiple": false,
5521
+ "options": [
5522
+ "compact",
5523
+ "json",
5524
+ "table"
5525
+ ],
5526
+ "type": "option"
5527
+ }
5528
+ },
5529
+ "hasDynamicHelp": false,
5530
+ "hiddenAliases": [],
5531
+ "id": "ai:actions:list",
5532
+ "pluginAlias": "@memberjunction/cli",
5533
+ "pluginName": "@memberjunction/cli",
5534
+ "pluginType": "core",
5535
+ "strict": true,
5536
+ "enableJsonFlag": false,
5537
+ "isESM": true,
5538
+ "relativePath": [
5539
+ "dist",
5540
+ "commands",
5541
+ "ai",
5542
+ "actions",
5543
+ "list.js"
5544
+ ]
5545
+ },
5546
+ "ai:actions:run": {
5547
+ "aliases": [],
5548
+ "args": {},
5549
+ "description": "Execute an AI action with parameters",
5550
+ "examples": [
5551
+ "<%= config.bin %> <%= command.id %> -n \"Get Weather\" --param \"Location=Boston\"",
5552
+ "<%= config.bin %> <%= command.id %> -n \"Get Stock Price\" --param \"Ticker=AAPL\"",
5553
+ "<%= config.bin %> <%= command.id %> -n \"Send Single Message\" --param \"To=user@example.com\" --param \"Subject=Test\" --param \"Body=Hello\" --param \"MessageType=Email\" --param \"Provider=SendGrid\"",
5554
+ "<%= config.bin %> <%= command.id %> -n \"Calculate Expression\" --param \"Expression=2+2*3\" --dry-run"
5555
+ ],
5556
+ "flags": {
5557
+ "name": {
5558
+ "char": "n",
5559
+ "description": "Action name",
5560
+ "name": "name",
5561
+ "required": true,
5562
+ "hasDynamicHelp": false,
5563
+ "multiple": false,
5564
+ "type": "option"
5565
+ },
5566
+ "param": {
5567
+ "char": "p",
5568
+ "description": "Action parameters in key=value format",
5569
+ "name": "param",
5570
+ "hasDynamicHelp": false,
5571
+ "multiple": true,
5572
+ "type": "option"
5573
+ },
5574
+ "dry-run": {
5575
+ "description": "Validate without executing",
5576
+ "name": "dry-run",
5577
+ "allowNo": false,
5578
+ "type": "boolean"
5579
+ },
5580
+ "format": {
5581
+ "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
5582
+ "name": "format",
5583
+ "hasDynamicHelp": false,
5584
+ "multiple": false,
5585
+ "options": [
5586
+ "text",
5587
+ "json",
5588
+ "md",
5589
+ "human",
5590
+ "console",
5591
+ "markdown",
5592
+ "compact",
5593
+ "table"
5594
+ ],
5595
+ "type": "option"
5596
+ },
5597
+ "output": {
5598
+ "char": "o",
5599
+ "description": "Output format (legacy alias for --format in the 'mj ai' family; elsewhere -o is an output FILE path). Prefer --format.",
5600
+ "name": "output",
5601
+ "default": "compact",
5602
+ "hasDynamicHelp": false,
5603
+ "multiple": false,
5604
+ "options": [
5605
+ "compact",
5412
5606
  "json",
5413
- "md"
5607
+ "table"
5414
5608
  ],
5415
5609
  "type": "option"
5610
+ },
5611
+ "verbose": {
5612
+ "char": "v",
5613
+ "description": "Show detailed execution information",
5614
+ "name": "verbose",
5615
+ "allowNo": false,
5616
+ "type": "boolean"
5617
+ },
5618
+ "timeout": {
5619
+ "description": "Execution timeout in milliseconds",
5620
+ "name": "timeout",
5621
+ "default": 300000,
5622
+ "hasDynamicHelp": false,
5623
+ "multiple": false,
5624
+ "type": "option"
5416
5625
  }
5417
5626
  },
5418
5627
  "hasDynamicHelp": false,
5419
5628
  "hiddenAliases": [],
5420
- "id": "update:usage",
5629
+ "id": "ai:actions:run",
5421
5630
  "pluginAlias": "@memberjunction/cli",
5422
5631
  "pluginName": "@memberjunction/cli",
5423
5632
  "pluginType": "core",
@@ -5427,14 +5636,15 @@
5427
5636
  "relativePath": [
5428
5637
  "dist",
5429
5638
  "commands",
5430
- "update",
5431
- "usage.js"
5639
+ "ai",
5640
+ "actions",
5641
+ "run.js"
5432
5642
  ]
5433
5643
  },
5434
- "ai:actions:list": {
5644
+ "ai:agents:list": {
5435
5645
  "aliases": [],
5436
5646
  "args": {},
5437
- "description": "List available AI actions",
5647
+ "description": "List available AI agents",
5438
5648
  "examples": [
5439
5649
  "<%= config.bin %> <%= command.id %>",
5440
5650
  "<%= config.bin %> <%= command.id %> --output=table",
@@ -5475,7 +5685,7 @@
5475
5685
  },
5476
5686
  "hasDynamicHelp": false,
5477
5687
  "hiddenAliases": [],
5478
- "id": "ai:actions:list",
5688
+ "id": "ai:agents:list",
5479
5689
  "pluginAlias": "@memberjunction/cli",
5480
5690
  "pluginName": "@memberjunction/cli",
5481
5691
  "pluginType": "core",
@@ -5486,41 +5696,47 @@
5486
5696
  "dist",
5487
5697
  "commands",
5488
5698
  "ai",
5489
- "actions",
5699
+ "agents",
5490
5700
  "list.js"
5491
5701
  ]
5492
5702
  },
5493
- "ai:actions:run": {
5703
+ "ai:agents:run": {
5494
5704
  "aliases": [],
5495
5705
  "args": {},
5496
- "description": "Execute an AI action with parameters",
5706
+ "description": "Execute an AI agent with a prompt or start interactive chat",
5497
5707
  "examples": [
5498
- "<%= config.bin %> <%= command.id %> -n \"Get Weather\" --param \"Location=Boston\"",
5499
- "<%= config.bin %> <%= command.id %> -n \"Get Stock Price\" --param \"Ticker=AAPL\"",
5500
- "<%= config.bin %> <%= command.id %> -n \"Send Single Message\" --param \"To=user@example.com\" --param \"Subject=Test\" --param \"Body=Hello\" --param \"MessageType=Email\" --param \"Provider=SendGrid\"",
5501
- "<%= config.bin %> <%= command.id %> -n \"Calculate Expression\" --param \"Expression=2+2*3\" --dry-run"
5708
+ "<%= config.bin %> <%= command.id %> -a \"Skip: Requirements Expert\" -p \"Create a dashboard for sales metrics\"",
5709
+ "<%= config.bin %> <%= command.id %> -a \"Child Component Generator Sub-agent\" --chat",
5710
+ "<%= config.bin %> <%= command.id %> -a \"Skip: Technical Design Expert\" -p \"Build a React component\" --verbose --timeout=600000"
5502
5711
  ],
5503
5712
  "flags": {
5504
- "name": {
5505
- "char": "n",
5506
- "description": "Action name",
5507
- "name": "name",
5713
+ "agent": {
5714
+ "char": "a",
5715
+ "description": "Agent name",
5716
+ "name": "agent",
5508
5717
  "required": true,
5509
5718
  "hasDynamicHelp": false,
5510
5719
  "multiple": false,
5511
5720
  "type": "option"
5512
5721
  },
5513
- "param": {
5722
+ "prompt": {
5514
5723
  "char": "p",
5515
- "description": "Action parameters in key=value format",
5516
- "name": "param",
5724
+ "description": "Prompt to execute",
5725
+ "exclusive": [
5726
+ "chat"
5727
+ ],
5728
+ "name": "prompt",
5517
5729
  "hasDynamicHelp": false,
5518
- "multiple": true,
5730
+ "multiple": false,
5519
5731
  "type": "option"
5520
5732
  },
5521
- "dry-run": {
5522
- "description": "Validate without executing",
5523
- "name": "dry-run",
5733
+ "chat": {
5734
+ "char": "c",
5735
+ "description": "Start interactive chat mode",
5736
+ "exclusive": [
5737
+ "prompt"
5738
+ ],
5739
+ "name": "chat",
5524
5740
  "allowNo": false,
5525
5741
  "type": "boolean"
5526
5742
  },
@@ -5573,7 +5789,7 @@
5573
5789
  },
5574
5790
  "hasDynamicHelp": false,
5575
5791
  "hiddenAliases": [],
5576
- "id": "ai:actions:run",
5792
+ "id": "ai:agents:run",
5577
5793
  "pluginAlias": "@memberjunction/cli",
5578
5794
  "pluginName": "@memberjunction/cli",
5579
5795
  "pluginType": "core",
@@ -5584,7 +5800,7 @@
5584
5800
  "dist",
5585
5801
  "commands",
5586
5802
  "ai",
5587
- "actions",
5803
+ "agents",
5588
5804
  "run.js"
5589
5805
  ]
5590
5806
  },
@@ -5821,169 +6037,6 @@
5821
6037
  "index.js"
5822
6038
  ]
5823
6039
  },
5824
- "ai:agents:list": {
5825
- "aliases": [],
5826
- "args": {},
5827
- "description": "List available AI agents",
5828
- "examples": [
5829
- "<%= config.bin %> <%= command.id %>",
5830
- "<%= config.bin %> <%= command.id %> --output=table",
5831
- "<%= config.bin %> <%= command.id %> --output=json"
5832
- ],
5833
- "flags": {
5834
- "format": {
5835
- "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
5836
- "name": "format",
5837
- "hasDynamicHelp": false,
5838
- "multiple": false,
5839
- "options": [
5840
- "text",
5841
- "json",
5842
- "md",
5843
- "human",
5844
- "console",
5845
- "markdown",
5846
- "compact",
5847
- "table"
5848
- ],
5849
- "type": "option"
5850
- },
5851
- "output": {
5852
- "char": "o",
5853
- "description": "Output format (legacy alias for --format in the 'mj ai' family; elsewhere -o is an output FILE path). Prefer --format.",
5854
- "name": "output",
5855
- "default": "compact",
5856
- "hasDynamicHelp": false,
5857
- "multiple": false,
5858
- "options": [
5859
- "compact",
5860
- "json",
5861
- "table"
5862
- ],
5863
- "type": "option"
5864
- }
5865
- },
5866
- "hasDynamicHelp": false,
5867
- "hiddenAliases": [],
5868
- "id": "ai:agents:list",
5869
- "pluginAlias": "@memberjunction/cli",
5870
- "pluginName": "@memberjunction/cli",
5871
- "pluginType": "core",
5872
- "strict": true,
5873
- "enableJsonFlag": false,
5874
- "isESM": true,
5875
- "relativePath": [
5876
- "dist",
5877
- "commands",
5878
- "ai",
5879
- "agents",
5880
- "list.js"
5881
- ]
5882
- },
5883
- "ai:agents:run": {
5884
- "aliases": [],
5885
- "args": {},
5886
- "description": "Execute an AI agent with a prompt or start interactive chat",
5887
- "examples": [
5888
- "<%= config.bin %> <%= command.id %> -a \"Skip: Requirements Expert\" -p \"Create a dashboard for sales metrics\"",
5889
- "<%= config.bin %> <%= command.id %> -a \"Child Component Generator Sub-agent\" --chat",
5890
- "<%= config.bin %> <%= command.id %> -a \"Skip: Technical Design Expert\" -p \"Build a React component\" --verbose --timeout=600000"
5891
- ],
5892
- "flags": {
5893
- "agent": {
5894
- "char": "a",
5895
- "description": "Agent name",
5896
- "name": "agent",
5897
- "required": true,
5898
- "hasDynamicHelp": false,
5899
- "multiple": false,
5900
- "type": "option"
5901
- },
5902
- "prompt": {
5903
- "char": "p",
5904
- "description": "Prompt to execute",
5905
- "exclusive": [
5906
- "chat"
5907
- ],
5908
- "name": "prompt",
5909
- "hasDynamicHelp": false,
5910
- "multiple": false,
5911
- "type": "option"
5912
- },
5913
- "chat": {
5914
- "char": "c",
5915
- "description": "Start interactive chat mode",
5916
- "exclusive": [
5917
- "prompt"
5918
- ],
5919
- "name": "chat",
5920
- "allowNo": false,
5921
- "type": "boolean"
5922
- },
5923
- "format": {
5924
- "description": "Output format: text (human), json (machine-readable), md (Markdown). Defaults to human output on a terminal and json when stdout is piped. Legacy spellings (console/markdown/compact/table) are accepted.",
5925
- "name": "format",
5926
- "hasDynamicHelp": false,
5927
- "multiple": false,
5928
- "options": [
5929
- "text",
5930
- "json",
5931
- "md",
5932
- "human",
5933
- "console",
5934
- "markdown",
5935
- "compact",
5936
- "table"
5937
- ],
5938
- "type": "option"
5939
- },
5940
- "output": {
5941
- "char": "o",
5942
- "description": "Output format (legacy alias for --format in the 'mj ai' family; elsewhere -o is an output FILE path). Prefer --format.",
5943
- "name": "output",
5944
- "default": "compact",
5945
- "hasDynamicHelp": false,
5946
- "multiple": false,
5947
- "options": [
5948
- "compact",
5949
- "json",
5950
- "table"
5951
- ],
5952
- "type": "option"
5953
- },
5954
- "verbose": {
5955
- "char": "v",
5956
- "description": "Show detailed execution information",
5957
- "name": "verbose",
5958
- "allowNo": false,
5959
- "type": "boolean"
5960
- },
5961
- "timeout": {
5962
- "description": "Execution timeout in milliseconds",
5963
- "name": "timeout",
5964
- "default": 300000,
5965
- "hasDynamicHelp": false,
5966
- "multiple": false,
5967
- "type": "option"
5968
- }
5969
- },
5970
- "hasDynamicHelp": false,
5971
- "hiddenAliases": [],
5972
- "id": "ai:agents:run",
5973
- "pluginAlias": "@memberjunction/cli",
5974
- "pluginName": "@memberjunction/cli",
5975
- "pluginType": "core",
5976
- "strict": true,
5977
- "enableJsonFlag": false,
5978
- "isESM": true,
5979
- "relativePath": [
5980
- "dist",
5981
- "commands",
5982
- "ai",
5983
- "agents",
5984
- "run.js"
5985
- ]
5986
- },
5987
6040
  "ai:prompts:list": {
5988
6041
  "aliases": [],
5989
6042
  "args": {},
@@ -6262,6 +6315,13 @@
6262
6315
  "multiple": true,
6263
6316
  "type": "option"
6264
6317
  },
6318
+ "apps": {
6319
+ "description": "Admit a member's app-shell packages, which the packages-rooted rule drops by default: <member>=<glob>[,<glob>] (e.g. Skip-Brain=apps/API,apps/MJAPI). The member must be detected or --include'd; names must be unique across the workspace.",
6320
+ "name": "apps",
6321
+ "hasDynamicHelp": false,
6322
+ "multiple": true,
6323
+ "type": "option"
6324
+ },
6265
6325
  "install": {
6266
6326
  "description": "Run `pnpm install` at the parent after generating (disable with --no-install)",
6267
6327
  "name": "install",
@@ -6787,5 +6847,5 @@
6787
6847
  ]
6788
6848
  }
6789
6849
  },
6790
- "version": "6.1.0-edge.5"
6850
+ "version": "6.1.0-edge.7"
6791
6851
  }