@memberjunction/cli 5.48.0 → 5.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1483,6 +1483,63 @@
1483
1483
  "usage.js"
1484
1484
  ]
1485
1485
  },
1486
+ "doctor": {
1487
+ "aliases": [],
1488
+ "args": {},
1489
+ "description": "Diagnose a MemberJunction installation",
1490
+ "examples": [
1491
+ "<%= config.bin %> <%= command.id %>",
1492
+ "<%= config.bin %> <%= command.id %> --dir ./my-mj-project",
1493
+ "<%= config.bin %> <%= command.id %> --verbose",
1494
+ "<%= config.bin %> <%= command.id %> --report",
1495
+ "<%= config.bin %> <%= command.id %> --report_extended"
1496
+ ],
1497
+ "flags": {
1498
+ "dir": {
1499
+ "description": "Target directory to diagnose",
1500
+ "name": "dir",
1501
+ "default": ".",
1502
+ "hasDynamicHelp": false,
1503
+ "multiple": false,
1504
+ "type": "option"
1505
+ },
1506
+ "verbose": {
1507
+ "char": "v",
1508
+ "description": "Show detailed output including suggested fixes inline",
1509
+ "name": "verbose",
1510
+ "allowNo": false,
1511
+ "type": "boolean"
1512
+ },
1513
+ "report": {
1514
+ "char": "r",
1515
+ "description": "Generate a diagnostic report file (mj-diagnostic-report.md) for sharing with support",
1516
+ "name": "report",
1517
+ "allowNo": false,
1518
+ "type": "boolean"
1519
+ },
1520
+ "report_extended": {
1521
+ "description": "Generate an extended report with config file snapshots and service startup log capture (~60s longer)",
1522
+ "name": "report_extended",
1523
+ "allowNo": false,
1524
+ "type": "boolean"
1525
+ }
1526
+ },
1527
+ "hasDynamicHelp": false,
1528
+ "hiddenAliases": [],
1529
+ "id": "doctor",
1530
+ "pluginAlias": "@memberjunction/cli",
1531
+ "pluginName": "@memberjunction/cli",
1532
+ "pluginType": "core",
1533
+ "strict": true,
1534
+ "enableJsonFlag": false,
1535
+ "isESM": true,
1536
+ "relativePath": [
1537
+ "dist",
1538
+ "commands",
1539
+ "doctor",
1540
+ "index.js"
1541
+ ]
1542
+ },
1486
1543
  "dbdoc:analyze": {
1487
1544
  "aliases": [],
1488
1545
  "args": {},
@@ -1920,50 +1977,90 @@
1920
1977
  "status.js"
1921
1978
  ]
1922
1979
  },
1923
- "doctor": {
1980
+ "migrate:convert": {
1924
1981
  "aliases": [],
1925
1982
  "args": {},
1926
- "description": "Diagnose a MemberJunction installation",
1983
+ "description": "Convert T-SQL migrations to PostgreSQL",
1927
1984
  "examples": [
1928
- "<%= config.bin %> <%= command.id %>",
1929
- "<%= config.bin %> <%= command.id %> --dir ./my-mj-project",
1930
- "<%= config.bin %> <%= command.id %> --verbose",
1931
- "<%= config.bin %> <%= command.id %> --report",
1932
- "<%= config.bin %> <%= command.id %> --report_extended"
1985
+ "<%= config.bin %> migrate convert --split",
1986
+ "<%= config.bin %> migrate convert --split --dry-run",
1987
+ "<%= config.bin %> migrate convert --split --file V202604060452__v5.24.x__KnowledgeHub.sql",
1988
+ "<%= config.bin %> migrate convert --source-dir ./migrations/v5 --output-dir ./migrations-pg/v5",
1989
+ "<%= config.bin %> migrate convert --verbose"
1933
1990
  ],
1934
1991
  "flags": {
1935
- "dir": {
1936
- "description": "Target directory to diagnose",
1937
- "name": "dir",
1938
- "default": ".",
1992
+ "source-dir": {
1993
+ "description": "Source T-SQL migrations directory",
1994
+ "name": "source-dir",
1995
+ "default": "./migrations/v5",
1996
+ "hasDynamicHelp": false,
1997
+ "multiple": false,
1998
+ "type": "option"
1999
+ },
2000
+ "output-dir": {
2001
+ "description": "Output PG migrations directory",
2002
+ "name": "output-dir",
2003
+ "default": "./migrations-pg/v5",
2004
+ "hasDynamicHelp": false,
2005
+ "multiple": false,
2006
+ "type": "option"
2007
+ },
2008
+ "file": {
2009
+ "description": "Convert a specific file (filename only, looked up in source-dir)",
2010
+ "name": "file",
2011
+ "hasDynamicHelp": false,
2012
+ "multiple": false,
2013
+ "type": "option"
2014
+ },
2015
+ "schema": {
2016
+ "description": "Target schema name",
2017
+ "name": "schema",
2018
+ "default": "__mj",
1939
2019
  "hasDynamicHelp": false,
1940
2020
  "multiple": false,
1941
2021
  "type": "option"
1942
2022
  },
2023
+ "dry-run": {
2024
+ "description": "Show what would be converted without writing files",
2025
+ "name": "dry-run",
2026
+ "allowNo": false,
2027
+ "type": "boolean"
2028
+ },
2029
+ "no-header": {
2030
+ "description": "Skip PG header (extensions, schema, implicit cast)",
2031
+ "name": "no-header",
2032
+ "allowNo": false,
2033
+ "type": "boolean"
2034
+ },
1943
2035
  "verbose": {
1944
2036
  "char": "v",
1945
- "description": "Show detailed output including suggested fixes inline",
2037
+ "description": "Show per-statement progress",
1946
2038
  "name": "verbose",
1947
2039
  "allowNo": false,
1948
2040
  "type": "boolean"
1949
2041
  },
1950
- "report": {
1951
- "char": "r",
1952
- "description": "Generate a diagnostic report file (mj-diagnostic-report.md) for sharing with support",
1953
- "name": "report",
2042
+ "split": {
2043
+ "description": "Split-and-regenerate (the standard path): transpile only hand-written DDL via the AST dialect; CodeGen objects are regenerated by `mj codegen` and mj-sync metadata re-seeded by `mj sync push`; every conversion gap is surfaced and fails the run unless --allow-gaps.",
2044
+ "name": "split",
1954
2045
  "allowNo": false,
1955
2046
  "type": "boolean"
1956
2047
  },
1957
- "report_extended": {
1958
- "description": "Generate an extended report with config file snapshots and service startup log capture (~60s longer)",
1959
- "name": "report_extended",
2048
+ "allow-gaps": {
2049
+ "description": "With --split: exit 0 even when migrations have conversion gaps (hand-authoring needed or unhandled statements). Gaps are still embedded as comments and listed in the summary.",
2050
+ "name": "allow-gaps",
2051
+ "allowNo": false,
2052
+ "type": "boolean"
2053
+ },
2054
+ "bake-codegen": {
2055
+ "description": "With --split: bake native PG CodeGen objects inline per migration (Path C), so the set deploys with `mj migrate` alone — no `mj codegen` step. Requires a LIVE working PG database (DB_PLATFORM=postgresql + PG_* env, same as `mj codegen`) seeded to the state just BEFORE the migrations being converted (typically the latest baseline); the converter brings it forward in committed order as it bakes. Not compatible with --dry-run.",
2056
+ "name": "bake-codegen",
1960
2057
  "allowNo": false,
1961
2058
  "type": "boolean"
1962
2059
  }
1963
2060
  },
1964
2061
  "hasDynamicHelp": false,
1965
2062
  "hiddenAliases": [],
1966
- "id": "doctor",
2063
+ "id": "migrate:convert",
1967
2064
  "pluginAlias": "@memberjunction/cli",
1968
2065
  "pluginName": "@memberjunction/cli",
1969
2066
  "pluginType": "core",
@@ -1973,110 +2070,63 @@
1973
2070
  "relativePath": [
1974
2071
  "dist",
1975
2072
  "commands",
1976
- "doctor",
1977
- "index.js"
2073
+ "migrate",
2074
+ "convert.js"
1978
2075
  ]
1979
2076
  },
1980
- "install:claude": {
2077
+ "migrate:create": {
1981
2078
  "aliases": [],
1982
- "args": {},
1983
- "description": "Install or refresh the Claude Code pack in the current directory.",
2079
+ "args": {
2080
+ "description": {
2081
+ "description": "Short description (will be converted to PascalCase with underscores)",
2082
+ "name": "description",
2083
+ "required": true
2084
+ }
2085
+ },
2086
+ "description": "Scaffold a new migration file for the current database platform",
1984
2087
  "examples": [
1985
- "<%= config.bin %> install:claude",
1986
- "<%= config.bin %> install:claude --dry-run",
1987
- "<%= config.bin %> install:claude --from ./local-pack",
1988
- "<%= config.bin %> install:claude --json"
2088
+ "<%= config.bin %> <%= command.id %> \"Add FooID to Bar\"",
2089
+ "<%= config.bin %> <%= command.id %> \"Add FooID to Bar\" --version 5.25 --platform postgresql",
2090
+ "<%= config.bin %> <%= command.id %> \"Add FooID to Bar\" --dir ./migrations/v5"
1989
2091
  ],
1990
2092
  "flags": {
1991
- "dir": {
1992
- "description": "Target directory for the install",
1993
- "name": "dir",
1994
- "default": ".",
1995
- "hasDynamicHelp": false,
1996
- "multiple": false,
1997
- "type": "option"
1998
- },
1999
- "major": {
2000
- "description": "Force a specific MJ major (default: detected from package.json)",
2001
- "name": "major",
2093
+ "version": {
2094
+ "char": "v",
2095
+ "description": "Migration version tag, e.g. \"5.25\" (default: parsed from repo baseline or \"0.0\")",
2096
+ "name": "version",
2002
2097
  "hasDynamicHelp": false,
2003
2098
  "multiple": false,
2004
2099
  "type": "option"
2005
2100
  },
2006
- "ref": {
2007
- "description": "Git ref to fetch from (branch or tag). Default: main.",
2008
- "name": "ref",
2101
+ "platform": {
2102
+ "char": "p",
2103
+ "description": "Override platform: sqlserver | postgresql (default: config.dbPlatform)",
2104
+ "name": "platform",
2009
2105
  "hasDynamicHelp": false,
2010
2106
  "multiple": false,
2107
+ "options": [
2108
+ "sqlserver",
2109
+ "postgresql"
2110
+ ],
2011
2111
  "type": "option"
2012
2112
  },
2013
- "from": {
2014
- "description": "Use a local pack source instead of fetching from GitHub",
2015
- "name": "from",
2113
+ "dir": {
2114
+ "description": "Output directory (default: ./migrations/v5 or ./migrations-pg/v5)",
2115
+ "name": "dir",
2016
2116
  "hasDynamicHelp": false,
2017
2117
  "multiple": false,
2018
2118
  "type": "option"
2019
2119
  },
2020
- "offline": {
2021
- "description": "Forbid network; requires --from <path>",
2022
- "name": "offline",
2023
- "allowNo": false,
2024
- "type": "boolean"
2025
- },
2026
- "dry-run": {
2027
- "description": "Print what would be written; change nothing",
2028
- "name": "dry-run",
2029
- "allowNo": false,
2030
- "type": "boolean"
2031
- },
2032
- "yes": {
2033
- "char": "y",
2034
- "description": "Don't prompt (reserved for future interactive paths; currently no-op)",
2035
- "name": "yes",
2036
- "allowNo": false,
2037
- "type": "boolean"
2038
- },
2039
- "force": {
2040
- "description": "Overwrite user-customized commands/skills (saves .bak files)",
2041
- "name": "force",
2042
- "allowNo": false,
2043
- "type": "boolean"
2044
- },
2045
- "skip-commands": {
2046
- "description": "Skip seeding .claude/commands/",
2047
- "name": "skip-commands",
2048
- "allowNo": false,
2049
- "type": "boolean"
2050
- },
2051
- "skip-skills": {
2052
- "description": "Skip seeding .claude/skills/",
2053
- "name": "skip-skills",
2054
- "allowNo": false,
2055
- "type": "boolean"
2056
- },
2057
- "skip-settings": {
2058
- "description": "Skip merging .claude/settings.json",
2059
- "name": "skip-settings",
2060
- "allowNo": false,
2061
- "type": "boolean"
2062
- },
2063
- "json": {
2064
- "description": "Output as JSON (matches plan §7.5 schema)",
2065
- "name": "json",
2066
- "allowNo": false,
2067
- "type": "boolean"
2068
- },
2069
- "verbose": {
2070
- "char": "v",
2071
- "description": "Show progress messages from the fetcher and merger",
2072
- "name": "verbose",
2120
+ "x-x": {
2121
+ "description": "Use {version}.x.x suffix instead of {version}.x (e.g. 5.25.x instead of 5.25.x)",
2122
+ "name": "x-x",
2073
2123
  "allowNo": false,
2074
2124
  "type": "boolean"
2075
2125
  }
2076
2126
  },
2077
2127
  "hasDynamicHelp": false,
2078
2128
  "hiddenAliases": [],
2079
- "id": "install:claude",
2129
+ "id": "migrate:create",
2080
2130
  "pluginAlias": "@memberjunction/cli",
2081
2131
  "pluginName": "@memberjunction/cli",
2082
2132
  "pluginType": "core",
@@ -2086,118 +2136,60 @@
2086
2136
  "relativePath": [
2087
2137
  "dist",
2088
2138
  "commands",
2089
- "install",
2090
- "claude.js"
2139
+ "migrate",
2140
+ "create.js"
2091
2141
  ]
2092
2142
  },
2093
- "install": {
2143
+ "migrate": {
2094
2144
  "aliases": [],
2095
2145
  "args": {},
2096
- "description": "Install MemberJunction from a GitHub release",
2146
+ "description": "Migrate MemberJunction database to latest version",
2097
2147
  "examples": [
2098
- "<%= config.bin %> <%= command.id %>",
2099
- "<%= config.bin %> <%= command.id %> -t v4.3.0",
2100
- "<%= config.bin %> <%= command.id %> --dry-run",
2101
- "<%= config.bin %> <%= command.id %> --yes"
2148
+ "<%= config.bin %> <%= command.id %>\n",
2149
+ "<%= config.bin %> <%= command.id %> --schema __BCSaaS --dir ./migrations/v1\n",
2150
+ "<%= config.bin %> <%= command.id %> --schema __BCSaaS --tag v1.0.0\n"
2102
2151
  ],
2103
2152
  "flags": {
2153
+ "verbose": {
2154
+ "char": "v",
2155
+ "description": "Enable additional logging",
2156
+ "name": "verbose",
2157
+ "allowNo": false,
2158
+ "type": "boolean"
2159
+ },
2104
2160
  "tag": {
2105
2161
  "char": "t",
2106
- "description": "Release tag to install (e.g. v4.3.0). If omitted, shows a version picker.",
2162
+ "description": "Version tag to use for running remote migrations",
2107
2163
  "name": "tag",
2108
2164
  "hasDynamicHelp": false,
2109
2165
  "multiple": false,
2110
2166
  "type": "option"
2111
2167
  },
2112
- "dir": {
2113
- "description": "Target directory for the installation",
2114
- "name": "dir",
2115
- "default": ".",
2168
+ "schema": {
2169
+ "char": "s",
2170
+ "description": "Target schema (overrides coreSchema from config)",
2171
+ "name": "schema",
2116
2172
  "hasDynamicHelp": false,
2117
2173
  "multiple": false,
2118
2174
  "type": "option"
2119
2175
  },
2120
- "config": {
2121
- "char": "c",
2122
- "description": "Path to JSON config file with install settings (database, auth, ports, etc.)",
2123
- "name": "config",
2176
+ "dir": {
2177
+ "description": "Migration source directory (overrides migrationsLocation from config)",
2178
+ "name": "dir",
2124
2179
  "hasDynamicHelp": false,
2125
2180
  "multiple": false,
2126
2181
  "type": "option"
2127
2182
  },
2128
- "legacy": {
2129
- "description": "Use the legacy interactive installer (ZIP-only distribution)",
2130
- "hidden": true,
2131
- "name": "legacy",
2132
- "allowNo": false,
2133
- "type": "boolean"
2134
- },
2135
- "dry-run": {
2136
- "description": "Show the install plan without executing it",
2137
- "name": "dry-run",
2138
- "allowNo": false,
2139
- "type": "boolean"
2140
- },
2141
- "yes": {
2142
- "char": "y",
2143
- "description": "Non-interactive mode: auto-select latest version and accept defaults",
2144
- "name": "yes",
2145
- "allowNo": false,
2146
- "type": "boolean"
2147
- },
2148
- "verbose": {
2149
- "char": "v",
2150
- "description": "Show detailed output",
2151
- "name": "verbose",
2152
- "allowNo": false,
2153
- "type": "boolean"
2154
- },
2155
- "skip-db": {
2156
- "description": "Skip database provisioning phases",
2157
- "name": "skip-db",
2158
- "allowNo": false,
2159
- "type": "boolean"
2160
- },
2161
- "skip-start": {
2162
- "description": "Skip service startup and smoke tests",
2163
- "name": "skip-start",
2164
- "allowNo": false,
2165
- "type": "boolean"
2166
- },
2167
- "no-resume": {
2168
- "description": "Ignore any existing checkpoint and start fresh",
2169
- "name": "no-resume",
2170
- "allowNo": false,
2171
- "type": "boolean"
2172
- },
2173
- "fast": {
2174
- "description": "Fast mode: skip smoke test and optimize post-codegen steps. Re-run without --fast if you encounter issues.",
2175
- "name": "fast",
2176
- "allowNo": false,
2177
- "type": "boolean"
2178
- },
2179
- "overwrite-config": {
2180
- "description": "Overwrite existing config files (.env, mj.config.cjs, environment.ts) instead of preserving them",
2181
- "name": "overwrite-config",
2182
- "allowNo": false,
2183
- "type": "boolean"
2184
- },
2185
- "monorepo": {
2186
- "description": "Install the full MemberJunction source repository instead of the lightweight distribution. Use this for MJ framework development.",
2187
- "name": "monorepo",
2188
- "allowNo": false,
2189
- "type": "boolean"
2190
- },
2191
- "no-claude-pack": {
2192
- "description": "Exclude the Claude Code pack (CLAUDE.md + .claude/ tree) from the scaffold. By default the pack ships with the install so opening Claude Code in your new MJ project gives you the curated MJ-aware experience immediately.",
2193
- "name": "no-claude-pack",
2183
+ "check-connection": {
2184
+ "description": "Verify the database connection (including TLS) and exit without migrating",
2185
+ "name": "check-connection",
2194
2186
  "allowNo": false,
2195
2187
  "type": "boolean"
2196
2188
  }
2197
2189
  },
2198
2190
  "hasDynamicHelp": false,
2199
2191
  "hiddenAliases": [],
2200
- "id": "install",
2192
+ "id": "migrate",
2201
2193
  "pluginAlias": "@memberjunction/cli",
2202
2194
  "pluginName": "@memberjunction/cli",
2203
2195
  "pluginType": "core",
@@ -2207,20 +2199,17 @@
2207
2199
  "relativePath": [
2208
2200
  "dist",
2209
2201
  "commands",
2210
- "install",
2202
+ "migrate",
2211
2203
  "index.js"
2212
2204
  ]
2213
2205
  },
2214
- "migrate:convert": {
2206
+ "migrate:rebake": {
2215
2207
  "aliases": [],
2216
2208
  "args": {},
2217
- "description": "Convert T-SQL migrations to PostgreSQL",
2209
+ "description": "Re-bake the post-baseline PG migration set with inline native CodeGen",
2218
2210
  "examples": [
2219
- "<%= config.bin %> migrate convert --split",
2220
- "<%= config.bin %> migrate convert --split --dry-run",
2221
- "<%= config.bin %> migrate convert --split --file V202604060452__v5.24.x__KnowledgeHub.sql",
2222
- "<%= config.bin %> migrate convert --source-dir ./migrations/v5 --output-dir ./migrations-pg/v5",
2223
- "<%= config.bin %> migrate convert --verbose"
2211
+ "<%= config.bin %> migrate rebake",
2212
+ "<%= config.bin %> migrate rebake --baseline-floor V202605291452 --dry-run"
2224
2213
  ],
2225
2214
  "flags": {
2226
2215
  "source-dir": {
@@ -2232,20 +2221,13 @@
2232
2221
  "type": "option"
2233
2222
  },
2234
2223
  "output-dir": {
2235
- "description": "Output PG migrations directory",
2224
+ "description": "PG migrations directory (committed files read here + baked output written here)",
2236
2225
  "name": "output-dir",
2237
2226
  "default": "./migrations-pg/v5",
2238
2227
  "hasDynamicHelp": false,
2239
2228
  "multiple": false,
2240
2229
  "type": "option"
2241
2230
  },
2242
- "file": {
2243
- "description": "Convert a specific file (filename only, looked up in source-dir)",
2244
- "name": "file",
2245
- "hasDynamicHelp": false,
2246
- "multiple": false,
2247
- "type": "option"
2248
- },
2249
2231
  "schema": {
2250
2232
  "description": "Target schema name",
2251
2233
  "name": "schema",
@@ -2254,47 +2236,23 @@
2254
2236
  "multiple": false,
2255
2237
  "type": "option"
2256
2238
  },
2239
+ "baseline-floor": {
2240
+ "description": "Re-bake migrations strictly AFTER this version key (default: the latest B* in output-dir)",
2241
+ "name": "baseline-floor",
2242
+ "hasDynamicHelp": false,
2243
+ "multiple": false,
2244
+ "type": "option"
2245
+ },
2257
2246
  "dry-run": {
2258
- "description": "Show what would be converted without writing files",
2247
+ "description": "Report what would be re-baked without writing files",
2259
2248
  "name": "dry-run",
2260
2249
  "allowNo": false,
2261
2250
  "type": "boolean"
2262
- },
2263
- "no-header": {
2264
- "description": "Skip PG header (extensions, schema, implicit cast)",
2265
- "name": "no-header",
2266
- "allowNo": false,
2267
- "type": "boolean"
2268
- },
2269
- "verbose": {
2270
- "char": "v",
2271
- "description": "Show per-statement progress",
2272
- "name": "verbose",
2273
- "allowNo": false,
2274
- "type": "boolean"
2275
- },
2276
- "split": {
2277
- "description": "Split-and-regenerate (the standard path): transpile only hand-written DDL via the AST dialect; CodeGen objects are regenerated by `mj codegen` and mj-sync metadata re-seeded by `mj sync push`; every conversion gap is surfaced and fails the run unless --allow-gaps.",
2278
- "name": "split",
2279
- "allowNo": false,
2280
- "type": "boolean"
2281
- },
2282
- "allow-gaps": {
2283
- "description": "With --split: exit 0 even when migrations have conversion gaps (hand-authoring needed or unhandled statements). Gaps are still embedded as comments and listed in the summary.",
2284
- "name": "allow-gaps",
2285
- "allowNo": false,
2286
- "type": "boolean"
2287
- },
2288
- "bake-codegen": {
2289
- "description": "With --split: bake native PG CodeGen objects inline per migration (Path C), so the set deploys with `mj migrate` alone — no `mj codegen` step. Requires a LIVE working PG database (DB_PLATFORM=postgresql + PG_* env, same as `mj codegen`) seeded to the state just BEFORE the migrations being converted (typically the latest baseline); the converter brings it forward in committed order as it bakes. Not compatible with --dry-run.",
2290
- "name": "bake-codegen",
2291
- "allowNo": false,
2292
- "type": "boolean"
2293
2251
  }
2294
2252
  },
2295
2253
  "hasDynamicHelp": false,
2296
2254
  "hiddenAliases": [],
2297
- "id": "migrate:convert",
2255
+ "id": "migrate:rebake",
2298
2256
  "pluginAlias": "@memberjunction/cli",
2299
2257
  "pluginName": "@memberjunction/cli",
2300
2258
  "pluginType": "core",
@@ -2305,62 +2263,40 @@
2305
2263
  "dist",
2306
2264
  "commands",
2307
2265
  "migrate",
2308
- "convert.js"
2266
+ "rebake.js"
2309
2267
  ]
2310
2268
  },
2311
- "migrate:create": {
2269
+ "plugin:add": {
2312
2270
  "aliases": [],
2313
2271
  "args": {
2314
- "description": {
2315
- "description": "Short description (will be converted to PascalCase with underscores)",
2316
- "name": "description",
2272
+ "package": {
2273
+ "description": "Plugin entry-point specifier (package name, subpath, or relative path)",
2274
+ "name": "package",
2317
2275
  "required": true
2318
2276
  }
2319
2277
  },
2320
- "description": "Scaffold a new migration file for the current database platform",
2278
+ "description": "Register a CLI plugin package in mj-cli-plugins.json so `mj` loads it at startup.",
2321
2279
  "examples": [
2322
- "<%= config.bin %> <%= command.id %> \"Add FooID to Bar\"",
2323
- "<%= config.bin %> <%= command.id %> \"Add FooID to Bar\" --version 5.25 --platform postgresql",
2324
- "<%= config.bin %> <%= command.id %> \"Add FooID to Bar\" --dir ./migrations/v5"
2280
+ "<%= config.bin %> <%= command.id %> @my-org/mj-plugin/plugins",
2281
+ "<%= config.bin %> <%= command.id %> ./local-plugins/my-tool"
2325
2282
  ],
2326
2283
  "flags": {
2327
- "version": {
2328
- "char": "v",
2329
- "description": "Migration version tag, e.g. \"5.25\" (default: parsed from repo baseline or \"0.0\")",
2330
- "name": "version",
2331
- "hasDynamicHelp": false,
2332
- "multiple": false,
2333
- "type": "option"
2334
- },
2335
- "platform": {
2336
- "char": "p",
2337
- "description": "Override platform: sqlserver | postgresql (default: config.dbPlatform)",
2338
- "name": "platform",
2284
+ "format": {
2285
+ "description": "Output format",
2286
+ "name": "format",
2287
+ "default": "text",
2339
2288
  "hasDynamicHelp": false,
2340
2289
  "multiple": false,
2341
2290
  "options": [
2342
- "sqlserver",
2343
- "postgresql"
2291
+ "text",
2292
+ "json"
2344
2293
  ],
2345
2294
  "type": "option"
2346
- },
2347
- "dir": {
2348
- "description": "Output directory (default: ./migrations/v5 or ./migrations-pg/v5)",
2349
- "name": "dir",
2350
- "hasDynamicHelp": false,
2351
- "multiple": false,
2352
- "type": "option"
2353
- },
2354
- "x-x": {
2355
- "description": "Use {version}.x.x suffix instead of {version}.x (e.g. 5.25.x instead of 5.25.x)",
2356
- "name": "x-x",
2357
- "allowNo": false,
2358
- "type": "boolean"
2359
2295
  }
2360
2296
  },
2361
2297
  "hasDynamicHelp": false,
2362
2298
  "hiddenAliases": [],
2363
- "id": "migrate:create",
2299
+ "id": "plugin:add",
2364
2300
  "pluginAlias": "@memberjunction/cli",
2365
2301
  "pluginName": "@memberjunction/cli",
2366
2302
  "pluginType": "core",
@@ -2370,60 +2306,110 @@
2370
2306
  "relativePath": [
2371
2307
  "dist",
2372
2308
  "commands",
2373
- "migrate",
2374
- "create.js"
2309
+ "plugin",
2310
+ "add.js"
2375
2311
  ]
2376
2312
  },
2377
- "migrate": {
2313
+ "install:claude": {
2378
2314
  "aliases": [],
2379
2315
  "args": {},
2380
- "description": "Migrate MemberJunction database to latest version",
2316
+ "description": "Install or refresh the Claude Code pack in the current directory.",
2381
2317
  "examples": [
2382
- "<%= config.bin %> <%= command.id %>\n",
2383
- "<%= config.bin %> <%= command.id %> --schema __BCSaaS --dir ./migrations/v1\n",
2384
- "<%= config.bin %> <%= command.id %> --schema __BCSaaS --tag v1.0.0\n"
2318
+ "<%= config.bin %> install:claude",
2319
+ "<%= config.bin %> install:claude --dry-run",
2320
+ "<%= config.bin %> install:claude --from ./local-pack",
2321
+ "<%= config.bin %> install:claude --json"
2385
2322
  ],
2386
2323
  "flags": {
2387
- "verbose": {
2388
- "char": "v",
2389
- "description": "Enable additional logging",
2390
- "name": "verbose",
2391
- "allowNo": false,
2392
- "type": "boolean"
2324
+ "dir": {
2325
+ "description": "Target directory for the install",
2326
+ "name": "dir",
2327
+ "default": ".",
2328
+ "hasDynamicHelp": false,
2329
+ "multiple": false,
2330
+ "type": "option"
2393
2331
  },
2394
- "tag": {
2395
- "char": "t",
2396
- "description": "Version tag to use for running remote migrations",
2397
- "name": "tag",
2332
+ "major": {
2333
+ "description": "Force a specific MJ major (default: detected from package.json)",
2334
+ "name": "major",
2398
2335
  "hasDynamicHelp": false,
2399
2336
  "multiple": false,
2400
2337
  "type": "option"
2401
2338
  },
2402
- "schema": {
2403
- "char": "s",
2404
- "description": "Target schema (overrides coreSchema from config)",
2405
- "name": "schema",
2339
+ "ref": {
2340
+ "description": "Git ref to fetch from (branch or tag). Default: main.",
2341
+ "name": "ref",
2406
2342
  "hasDynamicHelp": false,
2407
2343
  "multiple": false,
2408
2344
  "type": "option"
2409
2345
  },
2410
- "dir": {
2411
- "description": "Migration source directory (overrides migrationsLocation from config)",
2412
- "name": "dir",
2346
+ "from": {
2347
+ "description": "Use a local pack source instead of fetching from GitHub",
2348
+ "name": "from",
2413
2349
  "hasDynamicHelp": false,
2414
2350
  "multiple": false,
2415
2351
  "type": "option"
2416
2352
  },
2417
- "check-connection": {
2418
- "description": "Verify the database connection (including TLS) and exit without migrating",
2419
- "name": "check-connection",
2353
+ "offline": {
2354
+ "description": "Forbid network; requires --from <path>",
2355
+ "name": "offline",
2356
+ "allowNo": false,
2357
+ "type": "boolean"
2358
+ },
2359
+ "dry-run": {
2360
+ "description": "Print what would be written; change nothing",
2361
+ "name": "dry-run",
2362
+ "allowNo": false,
2363
+ "type": "boolean"
2364
+ },
2365
+ "yes": {
2366
+ "char": "y",
2367
+ "description": "Don't prompt (reserved for future interactive paths; currently no-op)",
2368
+ "name": "yes",
2369
+ "allowNo": false,
2370
+ "type": "boolean"
2371
+ },
2372
+ "force": {
2373
+ "description": "Overwrite user-customized commands/skills (saves .bak files)",
2374
+ "name": "force",
2375
+ "allowNo": false,
2376
+ "type": "boolean"
2377
+ },
2378
+ "skip-commands": {
2379
+ "description": "Skip seeding .claude/commands/",
2380
+ "name": "skip-commands",
2381
+ "allowNo": false,
2382
+ "type": "boolean"
2383
+ },
2384
+ "skip-skills": {
2385
+ "description": "Skip seeding .claude/skills/",
2386
+ "name": "skip-skills",
2387
+ "allowNo": false,
2388
+ "type": "boolean"
2389
+ },
2390
+ "skip-settings": {
2391
+ "description": "Skip merging .claude/settings.json",
2392
+ "name": "skip-settings",
2393
+ "allowNo": false,
2394
+ "type": "boolean"
2395
+ },
2396
+ "json": {
2397
+ "description": "Output as JSON (matches plan §7.5 schema)",
2398
+ "name": "json",
2399
+ "allowNo": false,
2400
+ "type": "boolean"
2401
+ },
2402
+ "verbose": {
2403
+ "char": "v",
2404
+ "description": "Show progress messages from the fetcher and merger",
2405
+ "name": "verbose",
2420
2406
  "allowNo": false,
2421
2407
  "type": "boolean"
2422
2408
  }
2423
2409
  },
2424
2410
  "hasDynamicHelp": false,
2425
2411
  "hiddenAliases": [],
2426
- "id": "migrate",
2412
+ "id": "install:claude",
2427
2413
  "pluginAlias": "@memberjunction/cli",
2428
2414
  "pluginName": "@memberjunction/cli",
2429
2415
  "pluginType": "core",
@@ -2433,104 +2419,118 @@
2433
2419
  "relativePath": [
2434
2420
  "dist",
2435
2421
  "commands",
2436
- "migrate",
2437
- "index.js"
2422
+ "install",
2423
+ "claude.js"
2438
2424
  ]
2439
2425
  },
2440
- "migrate:rebake": {
2426
+ "install": {
2441
2427
  "aliases": [],
2442
2428
  "args": {},
2443
- "description": "Re-bake the post-baseline PG migration set with inline native CodeGen",
2429
+ "description": "Install MemberJunction from a GitHub release",
2444
2430
  "examples": [
2445
- "<%= config.bin %> migrate rebake",
2446
- "<%= config.bin %> migrate rebake --baseline-floor V202605291452 --dry-run"
2431
+ "<%= config.bin %> <%= command.id %>",
2432
+ "<%= config.bin %> <%= command.id %> -t v4.3.0",
2433
+ "<%= config.bin %> <%= command.id %> --dry-run",
2434
+ "<%= config.bin %> <%= command.id %> --yes"
2447
2435
  ],
2448
2436
  "flags": {
2449
- "source-dir": {
2450
- "description": "Source T-SQL migrations directory",
2451
- "name": "source-dir",
2452
- "default": "./migrations/v5",
2437
+ "tag": {
2438
+ "char": "t",
2439
+ "description": "Release tag to install (e.g. v4.3.0). If omitted, shows a version picker.",
2440
+ "name": "tag",
2453
2441
  "hasDynamicHelp": false,
2454
2442
  "multiple": false,
2455
2443
  "type": "option"
2456
2444
  },
2457
- "output-dir": {
2458
- "description": "PG migrations directory (committed files read here + baked output written here)",
2459
- "name": "output-dir",
2460
- "default": "./migrations-pg/v5",
2445
+ "dir": {
2446
+ "description": "Target directory for the installation",
2447
+ "name": "dir",
2448
+ "default": ".",
2461
2449
  "hasDynamicHelp": false,
2462
2450
  "multiple": false,
2463
2451
  "type": "option"
2464
2452
  },
2465
- "schema": {
2466
- "description": "Target schema name",
2467
- "name": "schema",
2468
- "default": "__mj",
2453
+ "config": {
2454
+ "char": "c",
2455
+ "description": "Path to JSON config file with install settings (database, auth, ports, etc.)",
2456
+ "name": "config",
2469
2457
  "hasDynamicHelp": false,
2470
2458
  "multiple": false,
2471
2459
  "type": "option"
2472
2460
  },
2473
- "baseline-floor": {
2474
- "description": "Re-bake migrations strictly AFTER this version key (default: the latest B* in output-dir)",
2475
- "name": "baseline-floor",
2476
- "hasDynamicHelp": false,
2477
- "multiple": false,
2478
- "type": "option"
2461
+ "legacy": {
2462
+ "description": "Use the legacy interactive installer (ZIP-only distribution)",
2463
+ "hidden": true,
2464
+ "name": "legacy",
2465
+ "allowNo": false,
2466
+ "type": "boolean"
2479
2467
  },
2480
2468
  "dry-run": {
2481
- "description": "Report what would be re-baked without writing files",
2469
+ "description": "Show the install plan without executing it",
2482
2470
  "name": "dry-run",
2483
2471
  "allowNo": false,
2484
2472
  "type": "boolean"
2473
+ },
2474
+ "yes": {
2475
+ "char": "y",
2476
+ "description": "Non-interactive mode: auto-select latest version and accept defaults",
2477
+ "name": "yes",
2478
+ "allowNo": false,
2479
+ "type": "boolean"
2480
+ },
2481
+ "verbose": {
2482
+ "char": "v",
2483
+ "description": "Show detailed output",
2484
+ "name": "verbose",
2485
+ "allowNo": false,
2486
+ "type": "boolean"
2487
+ },
2488
+ "skip-db": {
2489
+ "description": "Skip database provisioning phases",
2490
+ "name": "skip-db",
2491
+ "allowNo": false,
2492
+ "type": "boolean"
2493
+ },
2494
+ "skip-start": {
2495
+ "description": "Skip service startup and smoke tests",
2496
+ "name": "skip-start",
2497
+ "allowNo": false,
2498
+ "type": "boolean"
2499
+ },
2500
+ "no-resume": {
2501
+ "description": "Ignore any existing checkpoint and start fresh",
2502
+ "name": "no-resume",
2503
+ "allowNo": false,
2504
+ "type": "boolean"
2505
+ },
2506
+ "fast": {
2507
+ "description": "Fast mode: skip smoke test and optimize post-codegen steps. Re-run without --fast if you encounter issues.",
2508
+ "name": "fast",
2509
+ "allowNo": false,
2510
+ "type": "boolean"
2511
+ },
2512
+ "overwrite-config": {
2513
+ "description": "Overwrite existing config files (.env, mj.config.cjs, environment.ts) instead of preserving them",
2514
+ "name": "overwrite-config",
2515
+ "allowNo": false,
2516
+ "type": "boolean"
2517
+ },
2518
+ "monorepo": {
2519
+ "description": "Install the full MemberJunction source repository instead of the lightweight distribution. Use this for MJ framework development.",
2520
+ "name": "monorepo",
2521
+ "allowNo": false,
2522
+ "type": "boolean"
2523
+ },
2524
+ "no-claude-pack": {
2525
+ "description": "Exclude the Claude Code pack (CLAUDE.md + .claude/ tree) from the scaffold. By default the pack ships with the install so opening Claude Code in your new MJ project gives you the curated MJ-aware experience immediately.",
2526
+ "name": "no-claude-pack",
2527
+ "allowNo": false,
2528
+ "type": "boolean"
2485
2529
  }
2486
2530
  },
2487
2531
  "hasDynamicHelp": false,
2488
2532
  "hiddenAliases": [],
2489
- "id": "migrate:rebake",
2490
- "pluginAlias": "@memberjunction/cli",
2491
- "pluginName": "@memberjunction/cli",
2492
- "pluginType": "core",
2493
- "strict": true,
2494
- "enableJsonFlag": false,
2495
- "isESM": true,
2496
- "relativePath": [
2497
- "dist",
2498
- "commands",
2499
- "migrate",
2500
- "rebake.js"
2501
- ]
2502
- },
2503
- "plugin:add": {
2504
- "aliases": [],
2505
- "args": {
2506
- "package": {
2507
- "description": "Plugin entry-point specifier (package name, subpath, or relative path)",
2508
- "name": "package",
2509
- "required": true
2510
- }
2511
- },
2512
- "description": "Register a CLI plugin package in mj-cli-plugins.json so `mj` loads it at startup.",
2513
- "examples": [
2514
- "<%= config.bin %> <%= command.id %> @my-org/mj-plugin/plugins",
2515
- "<%= config.bin %> <%= command.id %> ./local-plugins/my-tool"
2516
- ],
2517
- "flags": {
2518
- "format": {
2519
- "description": "Output format",
2520
- "name": "format",
2521
- "default": "text",
2522
- "hasDynamicHelp": false,
2523
- "multiple": false,
2524
- "options": [
2525
- "text",
2526
- "json"
2527
- ],
2528
- "type": "option"
2529
- }
2530
- },
2531
- "hasDynamicHelp": false,
2532
- "hiddenAliases": [],
2533
- "id": "plugin:add",
2533
+ "id": "install",
2534
2534
  "pluginAlias": "@memberjunction/cli",
2535
2535
  "pluginName": "@memberjunction/cli",
2536
2536
  "pluginType": "core",
@@ -2540,8 +2540,8 @@
2540
2540
  "relativePath": [
2541
2541
  "dist",
2542
2542
  "commands",
2543
- "plugin",
2544
- "add.js"
2543
+ "install",
2544
+ "index.js"
2545
2545
  ]
2546
2546
  },
2547
2547
  "querygen:export": {
@@ -2911,187 +2911,52 @@
2911
2911
  "index.js"
2912
2912
  ]
2913
2913
  },
2914
- "test:compare": {
2914
+ "sync:file-reset": {
2915
2915
  "aliases": [],
2916
- "args": {
2917
- "runId1": {
2918
- "description": "First test run ID to compare",
2919
- "name": "runId1",
2920
- "required": false
2921
- },
2922
- "runId2": {
2923
- "description": "Second test run ID to compare",
2924
- "name": "runId2",
2925
- "required": false
2926
- }
2927
- },
2928
- "description": "Compare test runs for regression detection",
2916
+ "args": {},
2917
+ "description": "Reset file metadata sections",
2929
2918
  "examples": [
2930
2919
  "<%= config.bin %> <%= command.id %>",
2931
- "<%= config.bin %> <%= command.id %> --latest",
2932
- "<%= config.bin %> <%= command.id %> <run-id-1> <run-id-2>",
2933
- "<%= config.bin %> <%= command.id %> -v 5.17.0 -v 5.18.0",
2934
- "<%= config.bin %> <%= command.id %> -c abc1234 -c def5678",
2935
- "<%= config.bin %> <%= command.id %> --from-json baseline.json latest.json",
2936
- "<%= config.bin %> <%= command.id %> --latest --format=markdown --output=report.md"
2920
+ "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
2921
+ "<%= config.bin %> <%= command.id %> --sections=\"dependencies,references\"",
2922
+ "<%= config.bin %> <%= command.id %> --all"
2937
2923
  ],
2938
2924
  "flags": {
2939
- "version": {
2940
- "char": "v",
2941
- "description": "Compare runs by version",
2942
- "name": "version",
2925
+ "dir": {
2926
+ "description": "Specific entity directory to reset",
2927
+ "name": "dir",
2943
2928
  "hasDynamicHelp": false,
2944
- "multiple": true,
2929
+ "multiple": false,
2945
2930
  "type": "option"
2946
2931
  },
2947
- "commit": {
2948
- "char": "c",
2949
- "description": "Compare runs by git commit",
2950
- "name": "commit",
2932
+ "sections": {
2933
+ "description": "Comma-separated list of sections to reset (dependencies,references,related,lookup)",
2934
+ "name": "sections",
2951
2935
  "hasDynamicHelp": false,
2952
- "multiple": true,
2936
+ "multiple": false,
2953
2937
  "type": "option"
2954
2938
  },
2955
- "diff-only": {
2956
- "description": "Show only differences",
2957
- "name": "diff-only",
2939
+ "all": {
2940
+ "description": "Reset all metadata sections",
2941
+ "name": "all",
2958
2942
  "allowNo": false,
2959
2943
  "type": "boolean"
2960
2944
  },
2961
- "latest": {
2962
- "char": "l",
2963
- "description": "Compare the two most recent completed suite runs",
2964
- "name": "latest",
2945
+ "dry-run": {
2946
+ "description": "Show what would be reset without actually resetting",
2947
+ "name": "dry-run",
2965
2948
  "allowNo": false,
2966
2949
  "type": "boolean"
2967
2950
  },
2968
- "from-json": {
2969
- "description": "Compare two results.json files directly (no DB). Pass twice: --from-json PREV --from-json CURR",
2970
- "name": "from-json",
2971
- "hasDynamicHelp": false,
2972
- "multiple": true,
2973
- "type": "option"
2974
- },
2975
- "format": {
2976
- "char": "f",
2977
- "description": "Output format",
2978
- "name": "format",
2979
- "default": "console",
2980
- "hasDynamicHelp": false,
2981
- "multiple": false,
2982
- "options": [
2983
- "console",
2984
- "json",
2985
- "markdown"
2986
- ],
2987
- "type": "option"
2988
- },
2989
- "output": {
2990
- "char": "o",
2991
- "description": "Output file path",
2992
- "name": "output",
2993
- "hasDynamicHelp": false,
2994
- "multiple": false,
2995
- "type": "option"
2996
- },
2997
- "verbose": {
2998
- "description": "Show detailed information",
2999
- "name": "verbose",
2951
+ "force": {
2952
+ "description": "Skip confirmation prompts",
2953
+ "name": "force",
3000
2954
  "allowNo": false,
3001
2955
  "type": "boolean"
3002
2956
  },
3003
- "tag": {
3004
- "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.",
3005
- "name": "tag",
3006
- "hasDynamicHelp": false,
3007
- "multiple": false,
3008
- "type": "option"
3009
- }
3010
- },
3011
- "hasDynamicHelp": false,
3012
- "hiddenAliases": [],
3013
- "id": "test:compare",
3014
- "pluginAlias": "@memberjunction/cli",
3015
- "pluginName": "@memberjunction/cli",
3016
- "pluginType": "core",
3017
- "strict": true,
3018
- "enableJsonFlag": false,
3019
- "isESM": true,
3020
- "relativePath": [
3021
- "dist",
3022
- "commands",
3023
- "test",
3024
- "compare.js"
3025
- ]
3026
- },
3027
- "test:history": {
3028
- "aliases": [],
3029
- "args": {},
3030
- "description": "View test execution history",
3031
- "examples": [
3032
- "<%= config.bin %> <%= command.id %>",
3033
- "<%= config.bin %> <%= command.id %> --test=<test-id>",
3034
- "<%= config.bin %> <%= command.id %> --suite=<suite-id>",
3035
- "<%= config.bin %> <%= command.id %> --since=\"2024-01-01\"",
3036
- "<%= config.bin %> <%= command.id %> --limit=50"
3037
- ],
3038
- "flags": {
3039
- "test": {
3040
- "char": "t",
3041
- "description": "Filter by test ID",
3042
- "name": "test",
3043
- "hasDynamicHelp": false,
3044
- "multiple": false,
3045
- "type": "option"
3046
- },
3047
- "recent": {
3048
- "char": "r",
3049
- "description": "Number of recent runs to show",
3050
- "name": "recent",
3051
- "hasDynamicHelp": false,
3052
- "multiple": false,
3053
- "type": "option"
3054
- },
3055
- "from": {
3056
- "description": "Show history from date (YYYY-MM-DD)",
3057
- "name": "from",
3058
- "hasDynamicHelp": false,
3059
- "multiple": false,
3060
- "type": "option"
3061
- },
3062
- "status": {
3063
- "char": "s",
3064
- "description": "Filter by status",
3065
- "name": "status",
3066
- "hasDynamicHelp": false,
3067
- "multiple": false,
3068
- "type": "option"
3069
- },
3070
- "format": {
3071
- "char": "f",
3072
- "description": "Output format",
3073
- "name": "format",
3074
- "default": "console",
3075
- "hasDynamicHelp": false,
3076
- "multiple": false,
3077
- "options": [
3078
- "console",
3079
- "json",
3080
- "markdown"
3081
- ],
3082
- "type": "option"
3083
- },
3084
- "output": {
3085
- "char": "o",
3086
- "description": "Output file path",
3087
- "name": "output",
3088
- "hasDynamicHelp": false,
3089
- "multiple": false,
3090
- "type": "option"
3091
- },
3092
2957
  "verbose": {
3093
2958
  "char": "v",
3094
- "description": "Show detailed information",
2959
+ "description": "Show detailed output",
3095
2960
  "name": "verbose",
3096
2961
  "allowNo": false,
3097
2962
  "type": "boolean"
@@ -3099,7 +2964,7 @@
3099
2964
  },
3100
2965
  "hasDynamicHelp": false,
3101
2966
  "hiddenAliases": [],
3102
- "id": "test:history",
2967
+ "id": "sync:file-reset",
3103
2968
  "pluginAlias": "@memberjunction/cli",
3104
2969
  "pluginName": "@memberjunction/cli",
3105
2970
  "pluginType": "core",
@@ -3109,26 +2974,21 @@
3109
2974
  "relativePath": [
3110
2975
  "dist",
3111
2976
  "commands",
3112
- "test",
3113
- "history.js"
2977
+ "sync",
2978
+ "file-reset.js"
3114
2979
  ]
3115
2980
  },
3116
- "test": {
2981
+ "sync:init": {
3117
2982
  "aliases": [],
3118
2983
  "args": {},
3119
- "description": "MemberJunction Testing Framework - Execute and manage tests",
2984
+ "description": "Initialize a directory for metadata synchronization",
3120
2985
  "examples": [
3121
- "<%= config.bin %> <%= command.id %> run <test-id>",
3122
- "<%= config.bin %> <%= command.id %> run --name=\"Active Members Count\"",
3123
- "<%= config.bin %> <%= command.id %> suite <suite-id>",
3124
- "<%= config.bin %> <%= command.id %> list",
3125
- "<%= config.bin %> <%= command.id %> list --suites",
3126
- "<%= config.bin %> <%= command.id %> validate --all"
2986
+ "<%= config.bin %> <%= command.id %>"
3127
2987
  ],
3128
2988
  "flags": {},
3129
2989
  "hasDynamicHelp": false,
3130
2990
  "hiddenAliases": [],
3131
- "id": "test",
2991
+ "id": "sync:init",
3132
2992
  "pluginAlias": "@memberjunction/cli",
3133
2993
  "pluginName": "@memberjunction/cli",
3134
2994
  "pluginType": "core",
@@ -3138,176 +2998,148 @@
3138
2998
  "relativePath": [
3139
2999
  "dist",
3140
3000
  "commands",
3141
- "test",
3142
- "index.js"
3001
+ "sync",
3002
+ "init.js"
3143
3003
  ]
3144
3004
  },
3145
- "test:list": {
3005
+ "sync:pull": {
3146
3006
  "aliases": [],
3147
3007
  "args": {},
3148
- "description": "List available tests, suites, and types",
3008
+ "description": "Pull metadata from database to local files",
3149
3009
  "examples": [
3150
- "<%= config.bin %> <%= command.id %>",
3151
- "<%= config.bin %> <%= command.id %> --suites",
3152
- "<%= config.bin %> <%= command.id %> --types",
3153
- "<%= config.bin %> <%= command.id %> --type=agent-eval",
3154
- "<%= config.bin %> <%= command.id %> --tag=smoke",
3155
- "<%= config.bin %> <%= command.id %> --status=active --verbose"
3010
+ "<%= config.bin %> <%= command.id %> --entity=\"MJ: AI Prompts\"",
3011
+ "<%= config.bin %> <%= command.id %> --entity=\"MJ: AI Agents\" --merge-strategy=overwrite",
3012
+ "<%= config.bin %> <%= command.id %> --entity=\"Templates\" --dry-run --verbose"
3156
3013
  ],
3157
3014
  "flags": {
3158
- "suites": {
3159
- "description": "List test suites instead of tests",
3160
- "name": "suites",
3015
+ "format": {
3016
+ "description": "Output format: text (human), json (machine-readable), md (Markdown-fenced)",
3017
+ "name": "format",
3018
+ "default": "text",
3019
+ "hasDynamicHelp": false,
3020
+ "multiple": false,
3021
+ "options": [
3022
+ "text",
3023
+ "json",
3024
+ "md"
3025
+ ],
3026
+ "type": "option"
3027
+ },
3028
+ "verbose": {
3029
+ "char": "v",
3030
+ "description": "Show detailed output",
3031
+ "name": "verbose",
3161
3032
  "allowNo": false,
3162
3033
  "type": "boolean"
3163
3034
  },
3164
- "types": {
3165
- "description": "List test types",
3166
- "name": "types",
3035
+ "no-banner": {
3036
+ "description": "Suppress the startup banner and runtime advisory",
3037
+ "name": "no-banner",
3167
3038
  "allowNo": false,
3168
3039
  "type": "boolean"
3169
3040
  },
3170
- "type": {
3171
- "char": "t",
3172
- "description": "Filter by test type",
3173
- "name": "type",
3041
+ "entity": {
3042
+ "description": "Entity name to pull",
3043
+ "name": "entity",
3044
+ "required": true,
3174
3045
  "hasDynamicHelp": false,
3175
3046
  "multiple": false,
3176
3047
  "type": "option"
3177
3048
  },
3178
- "tag": {
3179
- "description": "Filter by tag",
3180
- "name": "tag",
3049
+ "filter": {
3050
+ "description": "Additional filter for pulling specific records",
3051
+ "name": "filter",
3181
3052
  "hasDynamicHelp": false,
3182
3053
  "multiple": false,
3183
3054
  "type": "option"
3184
3055
  },
3185
- "status": {
3186
- "char": "s",
3187
- "description": "Filter by status",
3188
- "name": "status",
3189
- "hasDynamicHelp": false,
3190
- "multiple": false,
3191
- "type": "option"
3056
+ "dry-run": {
3057
+ "description": "Show what would be pulled without actually pulling",
3058
+ "name": "dry-run",
3059
+ "allowNo": false,
3060
+ "type": "boolean"
3192
3061
  },
3193
- "format": {
3194
- "char": "f",
3195
- "description": "Output format",
3196
- "name": "format",
3197
- "default": "console",
3062
+ "multi-file": {
3063
+ "description": "Create a single file with multiple records (provide filename)",
3064
+ "name": "multi-file",
3198
3065
  "hasDynamicHelp": false,
3199
3066
  "multiple": false,
3200
- "options": [
3201
- "console",
3202
- "json",
3203
- "markdown"
3204
- ],
3205
3067
  "type": "option"
3206
3068
  },
3207
- "output": {
3208
- "char": "o",
3209
- "description": "Output file path",
3210
- "name": "output",
3211
- "hasDynamicHelp": false,
3212
- "multiple": false,
3213
- "type": "option"
3069
+ "no-validate": {
3070
+ "description": "Skip validation before pull",
3071
+ "name": "no-validate",
3072
+ "allowNo": false,
3073
+ "type": "boolean"
3214
3074
  },
3215
- "verbose": {
3216
- "char": "v",
3217
- "description": "Show detailed information",
3218
- "name": "verbose",
3075
+ "update-existing": {
3076
+ "description": "Update existing records during pull",
3077
+ "name": "update-existing",
3219
3078
  "allowNo": false,
3220
3079
  "type": "boolean"
3221
- }
3222
- },
3223
- "hasDynamicHelp": false,
3224
- "hiddenAliases": [],
3225
- "id": "test:list",
3226
- "pluginAlias": "@memberjunction/cli",
3227
- "pluginName": "@memberjunction/cli",
3228
- "pluginType": "core",
3229
- "strict": true,
3230
- "enableJsonFlag": false,
3231
- "isESM": true,
3232
- "relativePath": [
3233
- "dist",
3234
- "commands",
3235
- "test",
3236
- "list.js"
3237
- ]
3238
- },
3239
- "test:run": {
3240
- "aliases": [],
3241
- "args": {
3242
- "testId": {
3243
- "description": "Test ID to execute",
3244
- "name": "testId",
3245
- "required": false
3246
- }
3247
- },
3248
- "description": "Execute a single test by ID or name",
3249
- "examples": [
3250
- "<%= config.bin %> <%= command.id %> <test-id>",
3251
- "<%= config.bin %> <%= command.id %> --name=\"Active Members Count\"",
3252
- "<%= config.bin %> <%= command.id %> <test-id> --environment=staging",
3253
- "<%= config.bin %> <%= command.id %> <test-id> --format=json --output=results.json",
3254
- "<%= config.bin %> <%= command.id %> <test-id> --dry-run"
3255
- ],
3256
- "flags": {
3257
- "name": {
3258
- "char": "n",
3259
- "description": "Test name to execute",
3260
- "name": "name",
3080
+ },
3081
+ "create-new": {
3082
+ "description": "Create new files for records not found locally",
3083
+ "name": "create-new",
3084
+ "allowNo": false,
3085
+ "type": "boolean"
3086
+ },
3087
+ "backup-before-update": {
3088
+ "description": "Create backups before updating files",
3089
+ "name": "backup-before-update",
3090
+ "allowNo": false,
3091
+ "type": "boolean"
3092
+ },
3093
+ "merge-strategy": {
3094
+ "description": "Merge strategy for updates",
3095
+ "name": "merge-strategy",
3096
+ "default": "merge",
3261
3097
  "hasDynamicHelp": false,
3262
3098
  "multiple": false,
3099
+ "options": [
3100
+ "merge",
3101
+ "overwrite",
3102
+ "skip"
3103
+ ],
3263
3104
  "type": "option"
3264
3105
  },
3265
- "environment": {
3266
- "char": "e",
3267
- "description": "Environment context (dev, staging, prod)",
3268
- "name": "environment",
3106
+ "backup-directory": {
3107
+ "description": "Custom backup directory (default: .backups)",
3108
+ "name": "backup-directory",
3269
3109
  "hasDynamicHelp": false,
3270
3110
  "multiple": false,
3271
3111
  "type": "option"
3272
3112
  },
3273
- "format": {
3274
- "char": "f",
3275
- "description": "Output format",
3276
- "name": "format",
3277
- "default": "console",
3113
+ "preserve-fields": {
3114
+ "description": "Comma-separated list of fields to preserve during updates",
3115
+ "name": "preserve-fields",
3278
3116
  "hasDynamicHelp": false,
3279
- "multiple": false,
3280
- "options": [
3281
- "console",
3282
- "json",
3283
- "markdown"
3284
- ],
3117
+ "multiple": true,
3285
3118
  "type": "option"
3286
3119
  },
3287
- "output": {
3288
- "char": "o",
3289
- "description": "Output file path",
3290
- "name": "output",
3120
+ "exclude-fields": {
3121
+ "description": "Comma-separated list of fields to exclude from pull",
3122
+ "name": "exclude-fields",
3291
3123
  "hasDynamicHelp": false,
3292
- "multiple": false,
3124
+ "multiple": true,
3293
3125
  "type": "option"
3294
3126
  },
3295
- "dry-run": {
3296
- "description": "Validate without executing",
3297
- "name": "dry-run",
3298
- "allowNo": false,
3299
- "type": "boolean"
3127
+ "target-dir": {
3128
+ "description": "Specific target directory (overrides auto-discovery)",
3129
+ "name": "target-dir",
3130
+ "hasDynamicHelp": false,
3131
+ "multiple": false,
3132
+ "type": "option"
3300
3133
  },
3301
- "verbose": {
3302
- "char": "v",
3303
- "description": "Show detailed execution information",
3304
- "name": "verbose",
3134
+ "incremental": {
3135
+ "description": "Only pull records updated since last successful pull",
3136
+ "name": "incremental",
3305
3137
  "allowNo": false,
3306
3138
  "type": "boolean"
3307
3139
  },
3308
- "oracles-module": {
3309
- "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.",
3310
- "name": "oracles-module",
3140
+ "since": {
3141
+ "description": "Only pull records updated after this ISO 8601 timestamp",
3142
+ "name": "since",
3311
3143
  "hasDynamicHelp": false,
3312
3144
  "multiple": false,
3313
3145
  "type": "option"
@@ -3315,268 +3147,270 @@
3315
3147
  },
3316
3148
  "hasDynamicHelp": false,
3317
3149
  "hiddenAliases": [],
3318
- "id": "test:run",
3150
+ "id": "sync:pull",
3319
3151
  "pluginAlias": "@memberjunction/cli",
3320
3152
  "pluginName": "@memberjunction/cli",
3321
3153
  "pluginType": "core",
3322
3154
  "strict": true,
3323
3155
  "enableJsonFlag": false,
3156
+ "Usage": {
3157
+ "domain": "sync",
3158
+ "command": "sync:pull",
3159
+ "summary": "Pull database records into local metadata files.",
3160
+ "description": "Writes records of --entity into the matching entity directory, creating or updating files per the merge strategy.",
3161
+ "flags": [
3162
+ {
3163
+ "name": "--entity",
3164
+ "type": "string",
3165
+ "description": "Entity name to pull (required)"
3166
+ },
3167
+ {
3168
+ "name": "--filter",
3169
+ "type": "string",
3170
+ "description": "Extra SQL filter for which records to pull"
3171
+ },
3172
+ {
3173
+ "name": "--merge-strategy",
3174
+ "type": "merge|overwrite|skip",
3175
+ "description": "How to reconcile existing files"
3176
+ },
3177
+ {
3178
+ "name": "--dry-run",
3179
+ "type": "boolean",
3180
+ "description": "Report what would be pulled without writing"
3181
+ },
3182
+ {
3183
+ "name": "--format",
3184
+ "type": "text|json|md",
3185
+ "description": "Output format (json for machine-readable result)"
3186
+ }
3187
+ ],
3188
+ "examples": [
3189
+ "mj sync pull --entity=\"MJ: AI Prompts\"",
3190
+ "mj sync pull --entity=\"Actions\" --format=json"
3191
+ ],
3192
+ "runtime": {
3193
+ "class": "variable",
3194
+ "typicalSeconds": 15,
3195
+ "note": "scales with number of records matched for --entity"
3196
+ }
3197
+ },
3324
3198
  "isESM": true,
3325
3199
  "relativePath": [
3326
3200
  "dist",
3327
3201
  "commands",
3328
- "test",
3329
- "run.js"
3202
+ "sync",
3203
+ "pull.js"
3330
3204
  ]
3331
3205
  },
3332
- "test:suite": {
3206
+ "sync:push": {
3333
3207
  "aliases": [],
3334
- "args": {
3335
- "suiteId": {
3336
- "description": "Test suite ID to execute",
3337
- "name": "suiteId",
3338
- "required": false
3339
- }
3340
- },
3341
- "description": "Execute a test suite",
3208
+ "args": {},
3209
+ "description": "Push local file changes to the database",
3342
3210
  "examples": [
3343
- "<%= config.bin %> <%= command.id %> <suite-id>",
3344
- "<%= config.bin %> <%= command.id %> --name=\"Agent Quality Suite\"",
3345
- "<%= config.bin %> <%= command.id %> <suite-id> --format=json",
3346
- "<%= config.bin %> <%= command.id %> <suite-id> --output=suite-results.json"
3211
+ "<%= config.bin %> <%= command.id %>",
3212
+ "<%= config.bin %> <%= command.id %> --dry-run",
3213
+ "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
3214
+ "<%= config.bin %> <%= command.id %> --ci --format=json"
3347
3215
  ],
3348
3216
  "flags": {
3349
- "name": {
3350
- "char": "n",
3351
- "description": "Test suite name to execute",
3352
- "name": "name",
3353
- "hasDynamicHelp": false,
3354
- "multiple": false,
3355
- "type": "option"
3356
- },
3357
3217
  "format": {
3358
- "char": "f",
3359
- "description": "Output format",
3218
+ "description": "Output format: text (human), json (machine-readable), md (Markdown-fenced)",
3360
3219
  "name": "format",
3361
- "default": "console",
3220
+ "default": "text",
3362
3221
  "hasDynamicHelp": false,
3363
3222
  "multiple": false,
3364
3223
  "options": [
3365
- "console",
3224
+ "text",
3366
3225
  "json",
3367
- "markdown"
3226
+ "md"
3368
3227
  ],
3369
3228
  "type": "option"
3370
3229
  },
3371
- "output": {
3372
- "char": "o",
3373
- "description": "Output file path",
3374
- "name": "output",
3375
- "hasDynamicHelp": false,
3376
- "multiple": false,
3377
- "type": "option"
3378
- },
3379
3230
  "verbose": {
3380
3231
  "char": "v",
3381
- "description": "Show detailed execution information",
3232
+ "description": "Show detailed output",
3382
3233
  "name": "verbose",
3383
3234
  "allowNo": false,
3384
3235
  "type": "boolean"
3385
3236
  },
3386
- "delay": {
3387
- "char": "d",
3388
- "description": "Delay in milliseconds between test executions (avoids Auth0 rate limits)",
3389
- "name": "delay",
3390
- "default": 0,
3391
- "hasDynamicHelp": false,
3392
- "multiple": false,
3393
- "type": "option"
3394
- },
3395
- "parallel": {
3396
- "char": "p",
3397
- "description": "Run tests in parallel with shared browser sessions",
3398
- "name": "parallel",
3237
+ "no-banner": {
3238
+ "description": "Suppress the startup banner and runtime advisory",
3239
+ "name": "no-banner",
3399
3240
  "allowNo": false,
3400
3241
  "type": "boolean"
3401
3242
  },
3402
- "max-parallel": {
3403
- "description": "Maximum number of parallel workers (default 4)",
3404
- "name": "max-parallel",
3405
- "default": 4,
3243
+ "dir": {
3244
+ "description": "Specific entity directory to push",
3245
+ "name": "dir",
3406
3246
  "hasDynamicHelp": false,
3407
3247
  "multiple": false,
3408
3248
  "type": "option"
3409
3249
  },
3410
- "flaky-check": {
3411
- "description": "Run each test N times to detect flakiness (variance > 0.3 or mixed pass/fail = flaky). Recommended: 3 or 5",
3412
- "name": "flaky-check",
3413
- "hasDynamicHelp": false,
3414
- "multiple": false,
3415
- "type": "option"
3250
+ "dry-run": {
3251
+ "description": "Show what would be pushed without actually pushing",
3252
+ "name": "dry-run",
3253
+ "allowNo": false,
3254
+ "type": "boolean"
3416
3255
  },
3417
- "oracles-module": {
3418
- "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.",
3419
- "name": "oracles-module",
3420
- "hasDynamicHelp": false,
3421
- "multiple": false,
3422
- "type": "option"
3423
- }
3424
- },
3425
- "hasDynamicHelp": false,
3426
- "hiddenAliases": [],
3427
- "id": "test:suite",
3428
- "pluginAlias": "@memberjunction/cli",
3429
- "pluginName": "@memberjunction/cli",
3430
- "pluginType": "core",
3431
- "strict": true,
3432
- "enableJsonFlag": false,
3433
- "isESM": true,
3434
- "relativePath": [
3435
- "dist",
3436
- "commands",
3437
- "test",
3438
- "suite.js"
3439
- ]
3440
- },
3441
- "test:validate": {
3442
- "aliases": [],
3443
- "args": {
3444
- "testId": {
3445
- "description": "Test ID to validate",
3446
- "name": "testId",
3447
- "required": false
3448
- }
3449
- },
3450
- "description": "Validate test definitions without executing",
3451
- "examples": [
3452
- "<%= config.bin %> <%= command.id %> <test-id>",
3453
- "<%= config.bin %> <%= command.id %> --all",
3454
- "<%= config.bin %> <%= command.id %> --type=agent-eval",
3455
- "<%= config.bin %> <%= command.id %> --all --save-report",
3456
- "<%= config.bin %> <%= command.id %> --all --output=validation-report.md"
3457
- ],
3458
- "flags": {
3459
- "all": {
3460
- "char": "a",
3461
- "description": "Validate all tests",
3462
- "name": "all",
3256
+ "ci": {
3257
+ "description": "CI mode - no prompts, fail on issues",
3258
+ "name": "ci",
3463
3259
  "allowNo": false,
3464
3260
  "type": "boolean"
3465
3261
  },
3466
- "type": {
3467
- "char": "t",
3468
- "description": "Validate tests by type",
3469
- "name": "type",
3470
- "hasDynamicHelp": false,
3471
- "multiple": false,
3472
- "type": "option"
3262
+ "no-validate": {
3263
+ "description": "Skip validation before push",
3264
+ "name": "no-validate",
3265
+ "allowNo": false,
3266
+ "type": "boolean"
3473
3267
  },
3474
- "save-report": {
3475
- "description": "Save validation report to file",
3476
- "name": "save-report",
3268
+ "delete-db-only": {
3269
+ "description": "Delete database-only records that reference records being deleted (prevents FK errors)",
3270
+ "name": "delete-db-only",
3477
3271
  "allowNo": false,
3478
3272
  "type": "boolean"
3479
3273
  },
3480
- "format": {
3481
- "char": "f",
3482
- "description": "Output format",
3483
- "name": "format",
3484
- "default": "console",
3274
+ "parallel-batch-size": {
3275
+ "description": "Number of records to process in parallel (default: 10)",
3276
+ "name": "parallel-batch-size",
3277
+ "default": 10,
3485
3278
  "hasDynamicHelp": false,
3486
3279
  "multiple": false,
3487
- "options": [
3488
- "console",
3489
- "json",
3490
- "markdown"
3491
- ],
3492
3280
  "type": "option"
3493
3281
  },
3494
- "output": {
3495
- "char": "o",
3496
- "description": "Output file path",
3497
- "name": "output",
3282
+ "include": {
3283
+ "description": "Only process these directories (comma-separated, supports patterns)",
3284
+ "name": "include",
3498
3285
  "hasDynamicHelp": false,
3499
3286
  "multiple": false,
3500
3287
  "type": "option"
3501
3288
  },
3502
- "verbose": {
3503
- "char": "v",
3504
- "description": "Show detailed information",
3505
- "name": "verbose",
3289
+ "exclude": {
3290
+ "description": "Skip these directories (comma-separated, supports patterns)",
3291
+ "name": "exclude",
3292
+ "hasDynamicHelp": false,
3293
+ "multiple": false,
3294
+ "type": "option"
3295
+ },
3296
+ "incremental": {
3297
+ "description": "Skip unchanged files using stored checksums from last push",
3298
+ "name": "incremental",
3299
+ "allowNo": false,
3300
+ "type": "boolean"
3301
+ },
3302
+ "change-detail": {
3303
+ "description": "Write a detailed per-record change report (primary keys + field diffs) to a file",
3304
+ "name": "change-detail",
3506
3305
  "allowNo": false,
3507
3306
  "type": "boolean"
3508
3307
  }
3509
3308
  },
3510
3309
  "hasDynamicHelp": false,
3511
3310
  "hiddenAliases": [],
3512
- "id": "test:validate",
3311
+ "id": "sync:push",
3513
3312
  "pluginAlias": "@memberjunction/cli",
3514
3313
  "pluginName": "@memberjunction/cli",
3515
3314
  "pluginType": "core",
3516
3315
  "strict": true,
3517
3316
  "enableJsonFlag": false,
3317
+ "Usage": {
3318
+ "domain": "sync",
3319
+ "command": "sync:push",
3320
+ "summary": "Push local metadata files to the database (upsert).",
3321
+ "description": "Reads entity directories under --dir and creates/updates matching records. Runs validation first unless --no-validate.",
3322
+ "flags": [
3323
+ {
3324
+ "name": "--dir",
3325
+ "type": "string",
3326
+ "description": "Entity directory to push"
3327
+ },
3328
+ {
3329
+ "name": "--dry-run",
3330
+ "type": "boolean",
3331
+ "description": "Report what would change without writing"
3332
+ },
3333
+ {
3334
+ "name": "--ci",
3335
+ "type": "boolean",
3336
+ "description": "No prompts; non-zero exit on error"
3337
+ },
3338
+ {
3339
+ "name": "--no-validate",
3340
+ "type": "boolean",
3341
+ "description": "Skip pre-push validation"
3342
+ },
3343
+ {
3344
+ "name": "--incremental",
3345
+ "type": "boolean",
3346
+ "description": "Skip unchanged files using stored checksums"
3347
+ },
3348
+ {
3349
+ "name": "--format",
3350
+ "type": "text|json|md",
3351
+ "description": "Output format (json for machine-readable result)"
3352
+ }
3353
+ ],
3354
+ "examples": [
3355
+ "mj sync push --dir=ai-agents",
3356
+ "mj sync push --ci --format=json"
3357
+ ],
3358
+ "runtime": {
3359
+ "class": "variable",
3360
+ "typicalSeconds": 20,
3361
+ "note": "scales with number of records in --dir"
3362
+ }
3363
+ },
3518
3364
  "isESM": true,
3519
3365
  "relativePath": [
3520
3366
  "dist",
3521
3367
  "commands",
3522
- "test",
3523
- "validate.js"
3368
+ "sync",
3369
+ "push.js"
3524
3370
  ]
3525
3371
  },
3526
- "sync:file-reset": {
3372
+ "sync:status": {
3527
3373
  "aliases": [],
3528
3374
  "args": {},
3529
- "description": "Reset file metadata sections",
3375
+ "description": "Show status of local files vs database",
3530
3376
  "examples": [
3531
3377
  "<%= config.bin %> <%= command.id %>",
3532
3378
  "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
3533
- "<%= config.bin %> <%= command.id %> --sections=\"dependencies,references\"",
3534
- "<%= config.bin %> <%= command.id %> --all"
3379
+ "<%= config.bin %> <%= command.id %> --verbose"
3535
3380
  ],
3536
3381
  "flags": {
3537
3382
  "dir": {
3538
- "description": "Specific entity directory to reset",
3383
+ "description": "Specific entity directory to check status",
3539
3384
  "name": "dir",
3540
3385
  "hasDynamicHelp": false,
3541
3386
  "multiple": false,
3542
3387
  "type": "option"
3543
3388
  },
3544
- "sections": {
3545
- "description": "Comma-separated list of sections to reset (dependencies,references,related,lookup)",
3546
- "name": "sections",
3547
- "hasDynamicHelp": false,
3548
- "multiple": false,
3549
- "type": "option"
3550
- },
3551
- "all": {
3552
- "description": "Reset all metadata sections",
3553
- "name": "all",
3554
- "allowNo": false,
3555
- "type": "boolean"
3556
- },
3557
- "dry-run": {
3558
- "description": "Show what would be reset without actually resetting",
3559
- "name": "dry-run",
3560
- "allowNo": false,
3561
- "type": "boolean"
3562
- },
3563
- "force": {
3564
- "description": "Skip confirmation prompts",
3565
- "name": "force",
3566
- "allowNo": false,
3567
- "type": "boolean"
3568
- },
3569
3389
  "verbose": {
3570
3390
  "char": "v",
3571
- "description": "Show detailed output",
3391
+ "description": "Show detailed field-level differences",
3572
3392
  "name": "verbose",
3573
3393
  "allowNo": false,
3574
3394
  "type": "boolean"
3395
+ },
3396
+ "include": {
3397
+ "description": "Only process these directories (comma-separated, supports patterns)",
3398
+ "name": "include",
3399
+ "hasDynamicHelp": false,
3400
+ "multiple": false,
3401
+ "type": "option"
3402
+ },
3403
+ "exclude": {
3404
+ "description": "Skip these directories (comma-separated, supports patterns)",
3405
+ "name": "exclude",
3406
+ "hasDynamicHelp": false,
3407
+ "multiple": false,
3408
+ "type": "option"
3575
3409
  }
3576
3410
  },
3577
3411
  "hasDynamicHelp": false,
3578
3412
  "hiddenAliases": [],
3579
- "id": "sync:file-reset",
3413
+ "id": "sync:status",
3580
3414
  "pluginAlias": "@memberjunction/cli",
3581
3415
  "pluginName": "@memberjunction/cli",
3582
3416
  "pluginType": "core",
@@ -3587,20 +3421,31 @@
3587
3421
  "dist",
3588
3422
  "commands",
3589
3423
  "sync",
3590
- "file-reset.js"
3424
+ "status.js"
3591
3425
  ]
3592
3426
  },
3593
- "sync:init": {
3427
+ "sync:usage": {
3594
3428
  "aliases": [],
3595
3429
  "args": {},
3596
- "description": "Initialize a directory for metadata synchronization",
3597
- "examples": [
3598
- "<%= config.bin %> <%= command.id %>"
3599
- ],
3600
- "flags": {},
3430
+ "description": "Show usage, flags, examples, and runtime hints for every `mj sync` command.",
3431
+ "flags": {
3432
+ "format": {
3433
+ "description": "Output format",
3434
+ "name": "format",
3435
+ "default": "text",
3436
+ "hasDynamicHelp": false,
3437
+ "multiple": false,
3438
+ "options": [
3439
+ "text",
3440
+ "json",
3441
+ "md"
3442
+ ],
3443
+ "type": "option"
3444
+ }
3445
+ },
3601
3446
  "hasDynamicHelp": false,
3602
3447
  "hiddenAliases": [],
3603
- "id": "sync:init",
3448
+ "id": "sync:usage",
3604
3449
  "pluginAlias": "@memberjunction/cli",
3605
3450
  "pluginName": "@memberjunction/cli",
3606
3451
  "pluginType": "core",
@@ -3611,147 +3456,211 @@
3611
3456
  "dist",
3612
3457
  "commands",
3613
3458
  "sync",
3614
- "init.js"
3459
+ "usage.js"
3615
3460
  ]
3616
3461
  },
3617
- "sync:pull": {
3462
+ "sync:validate": {
3618
3463
  "aliases": [],
3619
3464
  "args": {},
3620
- "description": "Pull metadata from database to local files",
3465
+ "description": "Validate metadata files",
3621
3466
  "examples": [
3622
- "<%= config.bin %> <%= command.id %> --entity=\"MJ: AI Prompts\"",
3623
- "<%= config.bin %> <%= command.id %> --entity=\"MJ: AI Agents\" --merge-strategy=overwrite",
3624
- "<%= config.bin %> <%= command.id %> --entity=\"Templates\" --dry-run --verbose"
3467
+ "<%= config.bin %> <%= command.id %>",
3468
+ "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
3469
+ "<%= config.bin %> <%= command.id %> --save-report",
3470
+ "<%= config.bin %> <%= command.id %> --verbose"
3625
3471
  ],
3626
3472
  "flags": {
3627
- "format": {
3628
- "description": "Output format: text (human), json (machine-readable), md (Markdown-fenced)",
3629
- "name": "format",
3630
- "default": "text",
3473
+ "dir": {
3474
+ "description": "Specific entity directory to validate",
3475
+ "name": "dir",
3631
3476
  "hasDynamicHelp": false,
3632
3477
  "multiple": false,
3633
- "options": [
3634
- "text",
3635
- "json",
3636
- "md"
3637
- ],
3638
3478
  "type": "option"
3639
3479
  },
3640
3480
  "verbose": {
3641
3481
  "char": "v",
3642
- "description": "Show detailed output",
3482
+ "description": "Show detailed validation output",
3643
3483
  "name": "verbose",
3644
3484
  "allowNo": false,
3645
3485
  "type": "boolean"
3646
3486
  },
3647
- "no-banner": {
3648
- "description": "Suppress the startup banner and runtime advisory",
3649
- "name": "no-banner",
3487
+ "save-report": {
3488
+ "description": "Save validation report as markdown file",
3489
+ "name": "save-report",
3650
3490
  "allowNo": false,
3651
3491
  "type": "boolean"
3652
3492
  },
3653
- "entity": {
3654
- "description": "Entity name to pull",
3655
- "name": "entity",
3656
- "required": true,
3493
+ "output": {
3494
+ "description": "Output file path for validation report (default: validation-report.md)",
3495
+ "name": "output",
3657
3496
  "hasDynamicHelp": false,
3658
3497
  "multiple": false,
3659
3498
  "type": "option"
3660
- },
3661
- "filter": {
3662
- "description": "Additional filter for pulling specific records",
3663
- "name": "filter",
3499
+ }
3500
+ },
3501
+ "hasDynamicHelp": false,
3502
+ "hiddenAliases": [],
3503
+ "id": "sync:validate",
3504
+ "pluginAlias": "@memberjunction/cli",
3505
+ "pluginName": "@memberjunction/cli",
3506
+ "pluginType": "core",
3507
+ "strict": true,
3508
+ "enableJsonFlag": false,
3509
+ "isESM": true,
3510
+ "relativePath": [
3511
+ "dist",
3512
+ "commands",
3513
+ "sync",
3514
+ "validate.js"
3515
+ ]
3516
+ },
3517
+ "sync:watch": {
3518
+ "aliases": [],
3519
+ "args": {},
3520
+ "description": "Watch for file changes and sync automatically",
3521
+ "examples": [
3522
+ "<%= config.bin %> <%= command.id %>",
3523
+ "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
3524
+ "<%= config.bin %> <%= command.id %> --debounce=1000",
3525
+ "<%= config.bin %> <%= command.id %> --no-validate"
3526
+ ],
3527
+ "flags": {
3528
+ "dir": {
3529
+ "description": "Specific entity directory to watch",
3530
+ "name": "dir",
3664
3531
  "hasDynamicHelp": false,
3665
3532
  "multiple": false,
3666
3533
  "type": "option"
3667
3534
  },
3668
- "dry-run": {
3669
- "description": "Show what would be pulled without actually pulling",
3670
- "name": "dry-run",
3671
- "allowNo": false,
3672
- "type": "boolean"
3673
- },
3674
- "multi-file": {
3675
- "description": "Create a single file with multiple records (provide filename)",
3676
- "name": "multi-file",
3535
+ "debounce": {
3536
+ "description": "Debounce delay in milliseconds (default: 500)",
3537
+ "name": "debounce",
3677
3538
  "hasDynamicHelp": false,
3678
3539
  "multiple": false,
3679
3540
  "type": "option"
3680
3541
  },
3681
3542
  "no-validate": {
3682
- "description": "Skip validation before pull",
3543
+ "description": "Skip validation before sync",
3683
3544
  "name": "no-validate",
3684
3545
  "allowNo": false,
3685
3546
  "type": "boolean"
3686
3547
  },
3687
- "update-existing": {
3688
- "description": "Update existing records during pull",
3689
- "name": "update-existing",
3690
- "allowNo": false,
3691
- "type": "boolean"
3692
- },
3693
- "create-new": {
3694
- "description": "Create new files for records not found locally",
3695
- "name": "create-new",
3696
- "allowNo": false,
3697
- "type": "boolean"
3698
- },
3699
- "backup-before-update": {
3700
- "description": "Create backups before updating files",
3701
- "name": "backup-before-update",
3548
+ "verbose": {
3549
+ "char": "v",
3550
+ "description": "Show detailed output",
3551
+ "name": "verbose",
3702
3552
  "allowNo": false,
3703
3553
  "type": "boolean"
3554
+ }
3555
+ },
3556
+ "hasDynamicHelp": false,
3557
+ "hiddenAliases": [],
3558
+ "id": "sync:watch",
3559
+ "pluginAlias": "@memberjunction/cli",
3560
+ "pluginName": "@memberjunction/cli",
3561
+ "pluginType": "core",
3562
+ "strict": true,
3563
+ "enableJsonFlag": false,
3564
+ "isESM": true,
3565
+ "relativePath": [
3566
+ "dist",
3567
+ "commands",
3568
+ "sync",
3569
+ "watch.js"
3570
+ ]
3571
+ },
3572
+ "test:compare": {
3573
+ "aliases": [],
3574
+ "args": {
3575
+ "runId1": {
3576
+ "description": "First test run ID to compare",
3577
+ "name": "runId1",
3578
+ "required": false
3704
3579
  },
3705
- "merge-strategy": {
3706
- "description": "Merge strategy for updates",
3707
- "name": "merge-strategy",
3708
- "default": "merge",
3580
+ "runId2": {
3581
+ "description": "Second test run ID to compare",
3582
+ "name": "runId2",
3583
+ "required": false
3584
+ }
3585
+ },
3586
+ "description": "Compare test runs for regression detection",
3587
+ "examples": [
3588
+ "<%= config.bin %> <%= command.id %>",
3589
+ "<%= config.bin %> <%= command.id %> --latest",
3590
+ "<%= config.bin %> <%= command.id %> <run-id-1> <run-id-2>",
3591
+ "<%= config.bin %> <%= command.id %> -v 5.17.0 -v 5.18.0",
3592
+ "<%= config.bin %> <%= command.id %> -c abc1234 -c def5678",
3593
+ "<%= config.bin %> <%= command.id %> --from-json baseline.json latest.json",
3594
+ "<%= config.bin %> <%= command.id %> --latest --format=markdown --output=report.md"
3595
+ ],
3596
+ "flags": {
3597
+ "version": {
3598
+ "char": "v",
3599
+ "description": "Compare runs by version",
3600
+ "name": "version",
3709
3601
  "hasDynamicHelp": false,
3710
- "multiple": false,
3711
- "options": [
3712
- "merge",
3713
- "overwrite",
3714
- "skip"
3715
- ],
3602
+ "multiple": true,
3716
3603
  "type": "option"
3717
3604
  },
3718
- "backup-directory": {
3719
- "description": "Custom backup directory (default: .backups)",
3720
- "name": "backup-directory",
3605
+ "commit": {
3606
+ "char": "c",
3607
+ "description": "Compare runs by git commit",
3608
+ "name": "commit",
3721
3609
  "hasDynamicHelp": false,
3722
- "multiple": false,
3610
+ "multiple": true,
3723
3611
  "type": "option"
3724
3612
  },
3725
- "preserve-fields": {
3726
- "description": "Comma-separated list of fields to preserve during updates",
3727
- "name": "preserve-fields",
3613
+ "diff-only": {
3614
+ "description": "Show only differences",
3615
+ "name": "diff-only",
3616
+ "allowNo": false,
3617
+ "type": "boolean"
3618
+ },
3619
+ "latest": {
3620
+ "char": "l",
3621
+ "description": "Compare the two most recent completed suite runs",
3622
+ "name": "latest",
3623
+ "allowNo": false,
3624
+ "type": "boolean"
3625
+ },
3626
+ "from-json": {
3627
+ "description": "Compare two results.json files directly (no DB). Pass twice: --from-json PREV --from-json CURR",
3628
+ "name": "from-json",
3728
3629
  "hasDynamicHelp": false,
3729
3630
  "multiple": true,
3730
3631
  "type": "option"
3731
3632
  },
3732
- "exclude-fields": {
3733
- "description": "Comma-separated list of fields to exclude from pull",
3734
- "name": "exclude-fields",
3633
+ "format": {
3634
+ "char": "f",
3635
+ "description": "Output format",
3636
+ "name": "format",
3637
+ "default": "console",
3735
3638
  "hasDynamicHelp": false,
3736
- "multiple": true,
3639
+ "multiple": false,
3640
+ "options": [
3641
+ "console",
3642
+ "json",
3643
+ "markdown"
3644
+ ],
3737
3645
  "type": "option"
3738
3646
  },
3739
- "target-dir": {
3740
- "description": "Specific target directory (overrides auto-discovery)",
3741
- "name": "target-dir",
3647
+ "output": {
3648
+ "char": "o",
3649
+ "description": "Output file path",
3650
+ "name": "output",
3742
3651
  "hasDynamicHelp": false,
3743
3652
  "multiple": false,
3744
3653
  "type": "option"
3745
3654
  },
3746
- "incremental": {
3747
- "description": "Only pull records updated since last successful pull",
3748
- "name": "incremental",
3655
+ "verbose": {
3656
+ "description": "Show detailed information",
3657
+ "name": "verbose",
3749
3658
  "allowNo": false,
3750
3659
  "type": "boolean"
3751
3660
  },
3752
- "since": {
3753
- "description": "Only pull records updated after this ISO 8601 timestamp",
3754
- "name": "since",
3661
+ "tag": {
3662
+ "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.",
3663
+ "name": "tag",
3755
3664
  "hasDynamicHelp": false,
3756
3665
  "multiple": false,
3757
3666
  "type": "option"
@@ -3759,262 +3668,311 @@
3759
3668
  },
3760
3669
  "hasDynamicHelp": false,
3761
3670
  "hiddenAliases": [],
3762
- "id": "sync:pull",
3671
+ "id": "test:compare",
3763
3672
  "pluginAlias": "@memberjunction/cli",
3764
3673
  "pluginName": "@memberjunction/cli",
3765
3674
  "pluginType": "core",
3766
3675
  "strict": true,
3767
3676
  "enableJsonFlag": false,
3768
- "Usage": {
3769
- "domain": "sync",
3770
- "command": "sync:pull",
3771
- "summary": "Pull database records into local metadata files.",
3772
- "description": "Writes records of --entity into the matching entity directory, creating or updating files per the merge strategy.",
3773
- "flags": [
3774
- {
3775
- "name": "--entity",
3776
- "type": "string",
3777
- "description": "Entity name to pull (required)"
3778
- },
3779
- {
3780
- "name": "--filter",
3781
- "type": "string",
3782
- "description": "Extra SQL filter for which records to pull"
3783
- },
3784
- {
3785
- "name": "--merge-strategy",
3786
- "type": "merge|overwrite|skip",
3787
- "description": "How to reconcile existing files"
3788
- },
3789
- {
3790
- "name": "--dry-run",
3791
- "type": "boolean",
3792
- "description": "Report what would be pulled without writing"
3793
- },
3794
- {
3795
- "name": "--format",
3796
- "type": "text|json|md",
3797
- "description": "Output format (json for machine-readable result)"
3798
- }
3799
- ],
3800
- "examples": [
3801
- "mj sync pull --entity=\"MJ: AI Prompts\"",
3802
- "mj sync pull --entity=\"Actions\" --format=json"
3803
- ],
3804
- "runtime": {
3805
- "class": "variable",
3806
- "typicalSeconds": 15,
3807
- "note": "scales with number of records matched for --entity"
3808
- }
3809
- },
3810
3677
  "isESM": true,
3811
3678
  "relativePath": [
3812
3679
  "dist",
3813
3680
  "commands",
3814
- "sync",
3815
- "pull.js"
3681
+ "test",
3682
+ "compare.js"
3816
3683
  ]
3817
3684
  },
3818
- "sync:push": {
3685
+ "test:history": {
3819
3686
  "aliases": [],
3820
3687
  "args": {},
3821
- "description": "Push local file changes to the database",
3688
+ "description": "View test execution history",
3822
3689
  "examples": [
3823
3690
  "<%= config.bin %> <%= command.id %>",
3824
- "<%= config.bin %> <%= command.id %> --dry-run",
3825
- "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
3826
- "<%= config.bin %> <%= command.id %> --ci --format=json"
3691
+ "<%= config.bin %> <%= command.id %> --test=<test-id>",
3692
+ "<%= config.bin %> <%= command.id %> --suite=<suite-id>",
3693
+ "<%= config.bin %> <%= command.id %> --since=\"2024-01-01\"",
3694
+ "<%= config.bin %> <%= command.id %> --limit=50"
3827
3695
  ],
3828
3696
  "flags": {
3697
+ "test": {
3698
+ "char": "t",
3699
+ "description": "Filter by test ID",
3700
+ "name": "test",
3701
+ "hasDynamicHelp": false,
3702
+ "multiple": false,
3703
+ "type": "option"
3704
+ },
3705
+ "recent": {
3706
+ "char": "r",
3707
+ "description": "Number of recent runs to show",
3708
+ "name": "recent",
3709
+ "hasDynamicHelp": false,
3710
+ "multiple": false,
3711
+ "type": "option"
3712
+ },
3713
+ "from": {
3714
+ "description": "Show history from date (YYYY-MM-DD)",
3715
+ "name": "from",
3716
+ "hasDynamicHelp": false,
3717
+ "multiple": false,
3718
+ "type": "option"
3719
+ },
3720
+ "status": {
3721
+ "char": "s",
3722
+ "description": "Filter by status",
3723
+ "name": "status",
3724
+ "hasDynamicHelp": false,
3725
+ "multiple": false,
3726
+ "type": "option"
3727
+ },
3829
3728
  "format": {
3830
- "description": "Output format: text (human), json (machine-readable), md (Markdown-fenced)",
3729
+ "char": "f",
3730
+ "description": "Output format",
3831
3731
  "name": "format",
3832
- "default": "text",
3732
+ "default": "console",
3833
3733
  "hasDynamicHelp": false,
3834
3734
  "multiple": false,
3835
3735
  "options": [
3836
- "text",
3736
+ "console",
3837
3737
  "json",
3838
- "md"
3738
+ "markdown"
3839
3739
  ],
3840
3740
  "type": "option"
3841
3741
  },
3842
- "verbose": {
3843
- "char": "v",
3844
- "description": "Show detailed output",
3845
- "name": "verbose",
3846
- "allowNo": false,
3847
- "type": "boolean"
3848
- },
3849
- "no-banner": {
3850
- "description": "Suppress the startup banner and runtime advisory",
3851
- "name": "no-banner",
3852
- "allowNo": false,
3853
- "type": "boolean"
3854
- },
3855
- "dir": {
3856
- "description": "Specific entity directory to push",
3857
- "name": "dir",
3742
+ "output": {
3743
+ "char": "o",
3744
+ "description": "Output file path",
3745
+ "name": "output",
3858
3746
  "hasDynamicHelp": false,
3859
3747
  "multiple": false,
3860
3748
  "type": "option"
3861
3749
  },
3862
- "dry-run": {
3863
- "description": "Show what would be pushed without actually pushing",
3864
- "name": "dry-run",
3750
+ "verbose": {
3751
+ "char": "v",
3752
+ "description": "Show detailed information",
3753
+ "name": "verbose",
3865
3754
  "allowNo": false,
3866
3755
  "type": "boolean"
3867
- },
3868
- "ci": {
3869
- "description": "CI mode - no prompts, fail on issues",
3870
- "name": "ci",
3756
+ }
3757
+ },
3758
+ "hasDynamicHelp": false,
3759
+ "hiddenAliases": [],
3760
+ "id": "test:history",
3761
+ "pluginAlias": "@memberjunction/cli",
3762
+ "pluginName": "@memberjunction/cli",
3763
+ "pluginType": "core",
3764
+ "strict": true,
3765
+ "enableJsonFlag": false,
3766
+ "isESM": true,
3767
+ "relativePath": [
3768
+ "dist",
3769
+ "commands",
3770
+ "test",
3771
+ "history.js"
3772
+ ]
3773
+ },
3774
+ "test": {
3775
+ "aliases": [],
3776
+ "args": {},
3777
+ "description": "MemberJunction Testing Framework - Execute and manage tests",
3778
+ "examples": [
3779
+ "<%= config.bin %> <%= command.id %> run <test-id>",
3780
+ "<%= config.bin %> <%= command.id %> run --name=\"Active Members Count\"",
3781
+ "<%= config.bin %> <%= command.id %> suite <suite-id>",
3782
+ "<%= config.bin %> <%= command.id %> list",
3783
+ "<%= config.bin %> <%= command.id %> list --suites",
3784
+ "<%= config.bin %> <%= command.id %> validate --all"
3785
+ ],
3786
+ "flags": {},
3787
+ "hasDynamicHelp": false,
3788
+ "hiddenAliases": [],
3789
+ "id": "test",
3790
+ "pluginAlias": "@memberjunction/cli",
3791
+ "pluginName": "@memberjunction/cli",
3792
+ "pluginType": "core",
3793
+ "strict": true,
3794
+ "enableJsonFlag": false,
3795
+ "isESM": true,
3796
+ "relativePath": [
3797
+ "dist",
3798
+ "commands",
3799
+ "test",
3800
+ "index.js"
3801
+ ]
3802
+ },
3803
+ "test:list": {
3804
+ "aliases": [],
3805
+ "args": {},
3806
+ "description": "List available tests, suites, and types",
3807
+ "examples": [
3808
+ "<%= config.bin %> <%= command.id %>",
3809
+ "<%= config.bin %> <%= command.id %> --suites",
3810
+ "<%= config.bin %> <%= command.id %> --types",
3811
+ "<%= config.bin %> <%= command.id %> --type=agent-eval",
3812
+ "<%= config.bin %> <%= command.id %> --tag=smoke",
3813
+ "<%= config.bin %> <%= command.id %> --status=active --verbose"
3814
+ ],
3815
+ "flags": {
3816
+ "suites": {
3817
+ "description": "List test suites instead of tests",
3818
+ "name": "suites",
3871
3819
  "allowNo": false,
3872
3820
  "type": "boolean"
3873
3821
  },
3874
- "no-validate": {
3875
- "description": "Skip validation before push",
3876
- "name": "no-validate",
3822
+ "types": {
3823
+ "description": "List test types",
3824
+ "name": "types",
3877
3825
  "allowNo": false,
3878
3826
  "type": "boolean"
3879
3827
  },
3880
- "delete-db-only": {
3881
- "description": "Delete database-only records that reference records being deleted (prevents FK errors)",
3882
- "name": "delete-db-only",
3883
- "allowNo": false,
3884
- "type": "boolean"
3828
+ "type": {
3829
+ "char": "t",
3830
+ "description": "Filter by test type",
3831
+ "name": "type",
3832
+ "hasDynamicHelp": false,
3833
+ "multiple": false,
3834
+ "type": "option"
3885
3835
  },
3886
- "parallel-batch-size": {
3887
- "description": "Number of records to process in parallel (default: 10)",
3888
- "name": "parallel-batch-size",
3889
- "default": 10,
3836
+ "tag": {
3837
+ "description": "Filter by tag",
3838
+ "name": "tag",
3890
3839
  "hasDynamicHelp": false,
3891
3840
  "multiple": false,
3892
3841
  "type": "option"
3893
3842
  },
3894
- "include": {
3895
- "description": "Only process these directories (comma-separated, supports patterns)",
3896
- "name": "include",
3843
+ "status": {
3844
+ "char": "s",
3845
+ "description": "Filter by status",
3846
+ "name": "status",
3897
3847
  "hasDynamicHelp": false,
3898
3848
  "multiple": false,
3899
3849
  "type": "option"
3900
3850
  },
3901
- "exclude": {
3902
- "description": "Skip these directories (comma-separated, supports patterns)",
3903
- "name": "exclude",
3851
+ "format": {
3852
+ "char": "f",
3853
+ "description": "Output format",
3854
+ "name": "format",
3855
+ "default": "console",
3904
3856
  "hasDynamicHelp": false,
3905
3857
  "multiple": false,
3858
+ "options": [
3859
+ "console",
3860
+ "json",
3861
+ "markdown"
3862
+ ],
3906
3863
  "type": "option"
3907
3864
  },
3908
- "incremental": {
3909
- "description": "Skip unchanged files using stored checksums from last push",
3910
- "name": "incremental",
3911
- "allowNo": false,
3912
- "type": "boolean"
3865
+ "output": {
3866
+ "char": "o",
3867
+ "description": "Output file path",
3868
+ "name": "output",
3869
+ "hasDynamicHelp": false,
3870
+ "multiple": false,
3871
+ "type": "option"
3913
3872
  },
3914
- "change-detail": {
3915
- "description": "Write a detailed per-record change report (primary keys + field diffs) to a file",
3916
- "name": "change-detail",
3873
+ "verbose": {
3874
+ "char": "v",
3875
+ "description": "Show detailed information",
3876
+ "name": "verbose",
3917
3877
  "allowNo": false,
3918
3878
  "type": "boolean"
3919
3879
  }
3920
3880
  },
3921
3881
  "hasDynamicHelp": false,
3922
3882
  "hiddenAliases": [],
3923
- "id": "sync:push",
3883
+ "id": "test:list",
3924
3884
  "pluginAlias": "@memberjunction/cli",
3925
3885
  "pluginName": "@memberjunction/cli",
3926
3886
  "pluginType": "core",
3927
3887
  "strict": true,
3928
3888
  "enableJsonFlag": false,
3929
- "Usage": {
3930
- "domain": "sync",
3931
- "command": "sync:push",
3932
- "summary": "Push local metadata files to the database (upsert).",
3933
- "description": "Reads entity directories under --dir and creates/updates matching records. Runs validation first unless --no-validate.",
3934
- "flags": [
3935
- {
3936
- "name": "--dir",
3937
- "type": "string",
3938
- "description": "Entity directory to push"
3939
- },
3940
- {
3941
- "name": "--dry-run",
3942
- "type": "boolean",
3943
- "description": "Report what would change without writing"
3944
- },
3945
- {
3946
- "name": "--ci",
3947
- "type": "boolean",
3948
- "description": "No prompts; non-zero exit on error"
3949
- },
3950
- {
3951
- "name": "--no-validate",
3952
- "type": "boolean",
3953
- "description": "Skip pre-push validation"
3954
- },
3955
- {
3956
- "name": "--incremental",
3957
- "type": "boolean",
3958
- "description": "Skip unchanged files using stored checksums"
3959
- },
3960
- {
3961
- "name": "--format",
3962
- "type": "text|json|md",
3963
- "description": "Output format (json for machine-readable result)"
3964
- }
3965
- ],
3966
- "examples": [
3967
- "mj sync push --dir=ai-agents",
3968
- "mj sync push --ci --format=json"
3969
- ],
3970
- "runtime": {
3971
- "class": "variable",
3972
- "typicalSeconds": 20,
3973
- "note": "scales with number of records in --dir"
3974
- }
3975
- },
3976
3889
  "isESM": true,
3977
3890
  "relativePath": [
3978
3891
  "dist",
3979
3892
  "commands",
3980
- "sync",
3981
- "push.js"
3893
+ "test",
3894
+ "list.js"
3982
3895
  ]
3983
3896
  },
3984
- "sync:status": {
3897
+ "test:run": {
3985
3898
  "aliases": [],
3986
- "args": {},
3987
- "description": "Show status of local files vs database",
3899
+ "args": {
3900
+ "testId": {
3901
+ "description": "Test ID to execute",
3902
+ "name": "testId",
3903
+ "required": false
3904
+ }
3905
+ },
3906
+ "description": "Execute a single test by ID or name",
3988
3907
  "examples": [
3989
- "<%= config.bin %> <%= command.id %>",
3990
- "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
3991
- "<%= config.bin %> <%= command.id %> --verbose"
3908
+ "<%= config.bin %> <%= command.id %> <test-id>",
3909
+ "<%= config.bin %> <%= command.id %> --name=\"Active Members Count\"",
3910
+ "<%= config.bin %> <%= command.id %> <test-id> --environment=staging",
3911
+ "<%= config.bin %> <%= command.id %> <test-id> --format=json --output=results.json",
3912
+ "<%= config.bin %> <%= command.id %> <test-id> --dry-run"
3992
3913
  ],
3993
3914
  "flags": {
3994
- "dir": {
3995
- "description": "Specific entity directory to check status",
3996
- "name": "dir",
3915
+ "name": {
3916
+ "char": "n",
3917
+ "description": "Test name to execute",
3918
+ "name": "name",
3919
+ "hasDynamicHelp": false,
3920
+ "multiple": false,
3921
+ "type": "option"
3922
+ },
3923
+ "environment": {
3924
+ "char": "e",
3925
+ "description": "Environment context (dev, staging, prod)",
3926
+ "name": "environment",
3927
+ "hasDynamicHelp": false,
3928
+ "multiple": false,
3929
+ "type": "option"
3930
+ },
3931
+ "format": {
3932
+ "char": "f",
3933
+ "description": "Output format",
3934
+ "name": "format",
3935
+ "default": "console",
3936
+ "hasDynamicHelp": false,
3937
+ "multiple": false,
3938
+ "options": [
3939
+ "console",
3940
+ "json",
3941
+ "markdown"
3942
+ ],
3943
+ "type": "option"
3944
+ },
3945
+ "output": {
3946
+ "char": "o",
3947
+ "description": "Output file path",
3948
+ "name": "output",
3997
3949
  "hasDynamicHelp": false,
3998
3950
  "multiple": false,
3999
3951
  "type": "option"
4000
3952
  },
3953
+ "dry-run": {
3954
+ "description": "Validate without executing",
3955
+ "name": "dry-run",
3956
+ "allowNo": false,
3957
+ "type": "boolean"
3958
+ },
4001
3959
  "verbose": {
4002
3960
  "char": "v",
4003
- "description": "Show detailed field-level differences",
3961
+ "description": "Show detailed execution information",
4004
3962
  "name": "verbose",
4005
3963
  "allowNo": false,
4006
3964
  "type": "boolean"
4007
3965
  },
4008
- "include": {
4009
- "description": "Only process these directories (comma-separated, supports patterns)",
4010
- "name": "include",
3966
+ "checks-module": {
3967
+ "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).",
3968
+ "name": "checks-module",
4011
3969
  "hasDynamicHelp": false,
4012
3970
  "multiple": false,
4013
3971
  "type": "option"
4014
3972
  },
4015
- "exclude": {
4016
- "description": "Skip these directories (comma-separated, supports patterns)",
4017
- "name": "exclude",
3973
+ "oracles-module": {
3974
+ "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.",
3975
+ "name": "oracles-module",
4018
3976
  "hasDynamicHelp": false,
4019
3977
  "multiple": false,
4020
3978
  "type": "option"
@@ -4022,7 +3980,7 @@
4022
3980
  },
4023
3981
  "hasDynamicHelp": false,
4024
3982
  "hiddenAliases": [],
4025
- "id": "sync:status",
3983
+ "id": "test:run",
4026
3984
  "pluginAlias": "@memberjunction/cli",
4027
3985
  "pluginName": "@memberjunction/cli",
4028
3986
  "pluginType": "core",
@@ -4032,79 +3990,105 @@
4032
3990
  "relativePath": [
4033
3991
  "dist",
4034
3992
  "commands",
4035
- "sync",
4036
- "status.js"
3993
+ "test",
3994
+ "run.js"
4037
3995
  ]
4038
3996
  },
4039
- "sync:usage": {
3997
+ "test:suite": {
4040
3998
  "aliases": [],
4041
- "args": {},
4042
- "description": "Show usage, flags, examples, and runtime hints for every `mj sync` command.",
3999
+ "args": {
4000
+ "suiteId": {
4001
+ "description": "Test suite ID to execute",
4002
+ "name": "suiteId",
4003
+ "required": false
4004
+ }
4005
+ },
4006
+ "description": "Execute a test suite",
4007
+ "examples": [
4008
+ "<%= config.bin %> <%= command.id %> <suite-id>",
4009
+ "<%= config.bin %> <%= command.id %> --name=\"Agent Quality Suite\"",
4010
+ "<%= config.bin %> <%= command.id %> <suite-id> --format=json",
4011
+ "<%= config.bin %> <%= command.id %> <suite-id> --output=suite-results.json"
4012
+ ],
4043
4013
  "flags": {
4014
+ "name": {
4015
+ "char": "n",
4016
+ "description": "Test suite name to execute",
4017
+ "name": "name",
4018
+ "hasDynamicHelp": false,
4019
+ "multiple": false,
4020
+ "type": "option"
4021
+ },
4044
4022
  "format": {
4023
+ "char": "f",
4045
4024
  "description": "Output format",
4046
4025
  "name": "format",
4047
- "default": "text",
4026
+ "default": "console",
4048
4027
  "hasDynamicHelp": false,
4049
4028
  "multiple": false,
4050
4029
  "options": [
4051
- "text",
4030
+ "console",
4052
4031
  "json",
4053
- "md"
4032
+ "markdown"
4054
4033
  ],
4055
4034
  "type": "option"
4056
- }
4057
- },
4058
- "hasDynamicHelp": false,
4059
- "hiddenAliases": [],
4060
- "id": "sync:usage",
4061
- "pluginAlias": "@memberjunction/cli",
4062
- "pluginName": "@memberjunction/cli",
4063
- "pluginType": "core",
4064
- "strict": true,
4065
- "enableJsonFlag": false,
4066
- "isESM": true,
4067
- "relativePath": [
4068
- "dist",
4069
- "commands",
4070
- "sync",
4071
- "usage.js"
4072
- ]
4073
- },
4074
- "sync:validate": {
4075
- "aliases": [],
4076
- "args": {},
4077
- "description": "Validate metadata files",
4078
- "examples": [
4079
- "<%= config.bin %> <%= command.id %>",
4080
- "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
4081
- "<%= config.bin %> <%= command.id %> --save-report",
4082
- "<%= config.bin %> <%= command.id %> --verbose"
4083
- ],
4084
- "flags": {
4085
- "dir": {
4086
- "description": "Specific entity directory to validate",
4087
- "name": "dir",
4035
+ },
4036
+ "output": {
4037
+ "char": "o",
4038
+ "description": "Output file path",
4039
+ "name": "output",
4088
4040
  "hasDynamicHelp": false,
4089
4041
  "multiple": false,
4090
4042
  "type": "option"
4091
4043
  },
4092
4044
  "verbose": {
4093
4045
  "char": "v",
4094
- "description": "Show detailed validation output",
4046
+ "description": "Show detailed execution information",
4095
4047
  "name": "verbose",
4096
4048
  "allowNo": false,
4097
4049
  "type": "boolean"
4098
4050
  },
4099
- "save-report": {
4100
- "description": "Save validation report as markdown file",
4101
- "name": "save-report",
4051
+ "delay": {
4052
+ "char": "d",
4053
+ "description": "Delay in milliseconds between test executions (avoids Auth0 rate limits)",
4054
+ "name": "delay",
4055
+ "default": 0,
4056
+ "hasDynamicHelp": false,
4057
+ "multiple": false,
4058
+ "type": "option"
4059
+ },
4060
+ "parallel": {
4061
+ "char": "p",
4062
+ "description": "Run tests in parallel with shared browser sessions",
4063
+ "name": "parallel",
4102
4064
  "allowNo": false,
4103
4065
  "type": "boolean"
4104
4066
  },
4105
- "output": {
4106
- "description": "Output file path for validation report (default: validation-report.md)",
4107
- "name": "output",
4067
+ "max-parallel": {
4068
+ "description": "Maximum number of parallel workers (default 4)",
4069
+ "name": "max-parallel",
4070
+ "default": 4,
4071
+ "hasDynamicHelp": false,
4072
+ "multiple": false,
4073
+ "type": "option"
4074
+ },
4075
+ "flaky-check": {
4076
+ "description": "Run each test N times to detect flakiness (variance > 0.3 or mixed pass/fail = flaky). Recommended: 3 or 5",
4077
+ "name": "flaky-check",
4078
+ "hasDynamicHelp": false,
4079
+ "multiple": false,
4080
+ "type": "option"
4081
+ },
4082
+ "checks-module": {
4083
+ "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).",
4084
+ "name": "checks-module",
4085
+ "hasDynamicHelp": false,
4086
+ "multiple": false,
4087
+ "type": "option"
4088
+ },
4089
+ "oracles-module": {
4090
+ "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.",
4091
+ "name": "oracles-module",
4108
4092
  "hasDynamicHelp": false,
4109
4093
  "multiple": false,
4110
4094
  "type": "option"
@@ -4112,7 +4096,7 @@
4112
4096
  },
4113
4097
  "hasDynamicHelp": false,
4114
4098
  "hiddenAliases": [],
4115
- "id": "sync:validate",
4099
+ "id": "test:suite",
4116
4100
  "pluginAlias": "@memberjunction/cli",
4117
4101
  "pluginName": "@memberjunction/cli",
4118
4102
  "pluginType": "core",
@@ -4122,44 +4106,74 @@
4122
4106
  "relativePath": [
4123
4107
  "dist",
4124
4108
  "commands",
4125
- "sync",
4126
- "validate.js"
4109
+ "test",
4110
+ "suite.js"
4127
4111
  ]
4128
4112
  },
4129
- "sync:watch": {
4113
+ "test:validate": {
4130
4114
  "aliases": [],
4131
- "args": {},
4132
- "description": "Watch for file changes and sync automatically",
4115
+ "args": {
4116
+ "testId": {
4117
+ "description": "Test ID to validate",
4118
+ "name": "testId",
4119
+ "required": false
4120
+ }
4121
+ },
4122
+ "description": "Validate test definitions without executing",
4133
4123
  "examples": [
4134
- "<%= config.bin %> <%= command.id %>",
4135
- "<%= config.bin %> <%= command.id %> --dir=\"ai-prompts\"",
4136
- "<%= config.bin %> <%= command.id %> --debounce=1000",
4137
- "<%= config.bin %> <%= command.id %> --no-validate"
4124
+ "<%= config.bin %> <%= command.id %> <test-id>",
4125
+ "<%= config.bin %> <%= command.id %> --all",
4126
+ "<%= config.bin %> <%= command.id %> --type=agent-eval",
4127
+ "<%= config.bin %> <%= command.id %> --all --save-report",
4128
+ "<%= config.bin %> <%= command.id %> --all --output=validation-report.md"
4138
4129
  ],
4139
4130
  "flags": {
4140
- "dir": {
4141
- "description": "Specific entity directory to watch",
4142
- "name": "dir",
4131
+ "all": {
4132
+ "char": "a",
4133
+ "description": "Validate all tests",
4134
+ "name": "all",
4135
+ "allowNo": false,
4136
+ "type": "boolean"
4137
+ },
4138
+ "type": {
4139
+ "char": "t",
4140
+ "description": "Validate tests by type",
4141
+ "name": "type",
4143
4142
  "hasDynamicHelp": false,
4144
4143
  "multiple": false,
4145
4144
  "type": "option"
4146
4145
  },
4147
- "debounce": {
4148
- "description": "Debounce delay in milliseconds (default: 500)",
4149
- "name": "debounce",
4146
+ "save-report": {
4147
+ "description": "Save validation report to file",
4148
+ "name": "save-report",
4149
+ "allowNo": false,
4150
+ "type": "boolean"
4151
+ },
4152
+ "format": {
4153
+ "char": "f",
4154
+ "description": "Output format",
4155
+ "name": "format",
4156
+ "default": "console",
4150
4157
  "hasDynamicHelp": false,
4151
4158
  "multiple": false,
4159
+ "options": [
4160
+ "console",
4161
+ "json",
4162
+ "markdown"
4163
+ ],
4152
4164
  "type": "option"
4153
4165
  },
4154
- "no-validate": {
4155
- "description": "Skip validation before sync",
4156
- "name": "no-validate",
4157
- "allowNo": false,
4158
- "type": "boolean"
4166
+ "output": {
4167
+ "char": "o",
4168
+ "description": "Output file path",
4169
+ "name": "output",
4170
+ "hasDynamicHelp": false,
4171
+ "multiple": false,
4172
+ "type": "option"
4159
4173
  },
4160
4174
  "verbose": {
4161
4175
  "char": "v",
4162
- "description": "Show detailed output",
4176
+ "description": "Show detailed information",
4163
4177
  "name": "verbose",
4164
4178
  "allowNo": false,
4165
4179
  "type": "boolean"
@@ -4167,7 +4181,7 @@
4167
4181
  },
4168
4182
  "hasDynamicHelp": false,
4169
4183
  "hiddenAliases": [],
4170
- "id": "sync:watch",
4184
+ "id": "test:validate",
4171
4185
  "pluginAlias": "@memberjunction/cli",
4172
4186
  "pluginName": "@memberjunction/cli",
4173
4187
  "pluginType": "core",
@@ -4177,8 +4191,8 @@
4177
4191
  "relativePath": [
4178
4192
  "dist",
4179
4193
  "commands",
4180
- "sync",
4181
- "watch.js"
4194
+ "test",
4195
+ "validate.js"
4182
4196
  ]
4183
4197
  },
4184
4198
  "translate-sql": {
@@ -5466,5 +5480,5 @@
5466
5480
  ]
5467
5481
  }
5468
5482
  },
5469
- "version": "5.48.0"
5483
+ "version": "5.49.0"
5470
5484
  }