You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by ar...@apache.org on 2020/12/20 07:33:18 UTC

[incubator-nlpcraft] 03/07: Various improvements.

This is an automated email from the ASF dual-hosted git repository.

aradzinski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git

commit 39b18968fe7cf63d0b52931142be1e6a719b846f
Author: Aaron Radzinski <ar...@datalingvo.com>
AuthorDate: Sat Dec 19 16:10:57 2020 -0800

    Various improvements.
---
 .../nlpcraft/model/tools/cmdline/NCCli.scala       | 521 +++++++++++----------
 .../model/tools/cmdline/NCCliCommands.scala        | 167 +++----
 2 files changed, 356 insertions(+), 332 deletions(-)

diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCli.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCli.scala
index ee8fd55..17126b0 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCli.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCli.scala
@@ -94,20 +94,21 @@ object NCCli extends App {
     private final val DFLT_USER_EMAIL = "admin@admin.com"
     private final val DFLT_USER_PASSWD = "admin"
 
-    private final lazy val VER = NCVersion.getCurrent
-    private final lazy val JAVA = U.sysEnv("NLPCRAFT_CLI_JAVA").getOrElse(new File(SystemUtils.getJavaHome, s"bin/java${if (SystemUtils.IS_OS_UNIX) "" else ".exe"}").getAbsolutePath)
-    private final lazy val INSTALL_HOME = U.sysEnv("NLPCRAFT_CLI_INSTALL_HOME").getOrElse(SystemUtils.USER_DIR)
-    private final lazy val WORK_DIR = Paths.get("").toAbsolutePath.toString
-    private final lazy val JAVA_CP = U.sysEnv("NLPCRAFT_CLI_CP").getOrElse(ManagementFactory.getRuntimeMXBean.getClassPath)
-    private final lazy val SCRIPT_NAME = U.sysEnv("NLPCRAFT_CLI_SCRIPT").getOrElse(s"nlpcraft.${if (SystemUtils.IS_OS_UNIX) "sh" else "cmd"}")
-    private final lazy val PROMPT = if (SCRIPT_NAME.endsWith("cmd")) ">" else "$"
-    private final lazy val IS_SCRIPT = U.sysEnv("NLPCRAFT_CLI").isDefined
-
+    private final val VER = NCVersion.getCurrent
+    private final val CP_WIN_NIX_SEPS = ":;"
+    private final val CP_SEP = File.pathSeparator
+    private final val JAVA = U.sysEnv("NLPCRAFT_CLI_JAVA").getOrElse(new File(SystemUtils.getJavaHome, s"bin/java${if (SystemUtils.IS_OS_UNIX) "" else ".exe"}").getAbsolutePath)
+    private final val USR_WORK_DIR = SystemUtils.USER_DIR
+    private final val USR_HOME_DIR = SystemUtils.USER_HOME
+    private final val INSTALL_HOME = U.sysEnv("NLPCRAFT_CLI_INSTALL_HOME").getOrElse(USR_WORK_DIR)
+    private final val JAVA_CP = U.sysEnv("NLPCRAFT_CLI_CP").getOrElse(ManagementFactory.getRuntimeMXBean.getClassPath)
+    private final val SCRIPT_NAME = U.sysEnv("NLPCRAFT_CLI_SCRIPT").getOrElse(s"nlpcraft.${if (SystemUtils.IS_OS_UNIX) "sh" else "cmd"}")
+    private final val PROMPT = if (SCRIPT_NAME.endsWith("cmd")) ">" else "$"
+    private final val IS_SCRIPT = U.sysEnv("NLPCRAFT_CLI").isDefined
     private final val T___ = "    "
-    private val OPEN_BRK = Seq('[', '{', '(')
-    private val CLOSE_BRK = Seq(']', '}', ')')
-    // Pair for each open or close bracket.
-    private val BRK_PAIR = OPEN_BRK.zip(CLOSE_BRK).toMap ++ CLOSE_BRK.zip(OPEN_BRK).toMap
+    private final val OPEN_BRK = Seq('[', '{', '(')
+    private final val CLOSE_BRK = Seq(']', '}', ')')
+    private final val BRK_PAIR = OPEN_BRK.zip(CLOSE_BRK).toMap ++ CLOSE_BRK.zip(OPEN_BRK).toMap // Pair for each open or close bracket.
 
     private var exitStatus = 0
 
@@ -270,6 +271,125 @@ object NCCli extends App {
     private final val STOP_PRB_CMD = CMDS.find(_.name == "stop-probe").get
 
     /**
+     * @param cmd
+     * @param args
+     * @param id
+     * @param dflt
+     */
+    @throws[MissingParameter]
+    private def getParam(cmd: Command, args: Seq[Argument], id: String, dflt: String = null): String =
+        args.find(_.parameter.id == id).flatMap(_.value) match {
+            case Some(v) ⇒ v
+            case None ⇒
+                if (dflt == null)
+                    throw MissingParameter(cmd, id)
+
+                dflt
+        }
+
+    @throws[InvalidParameter]
+    private def getIntParam(cmd: Command, args: Seq[Argument], id: String, dflt: Int): Int = {
+        getParamOpt(cmd, args, id) match {
+            case Some(num) ⇒
+                try
+                    Integer.parseInt(num)
+                catch {
+                    case _: Exception ⇒ throw InvalidParameter(cmd, id)
+                }
+
+            case None ⇒ dflt // Default.
+        }
+    }
+
+    @throws[InvalidParameter]
+    private def getDoubleParam(cmd: Command, args: Seq[Argument], id: String, dflt: Double): Double = {
+        getParamOpt(cmd, args, id) match {
+            case Some(num) ⇒
+                try
+                    java.lang.Double.parseDouble(num)
+                catch {
+                    case _: Exception ⇒ throw InvalidParameter(cmd, id)
+                }
+
+            case None ⇒ dflt // Default.
+        }
+    }
+
+    /**
+     * @param cmd
+     * @param args
+     * @param id
+     */
+    private def getParamOpt(cmd: Command, args: Seq[Argument], id: String): Option[String] =
+        args.find(_.parameter.id == id).flatMap(_.value)
+
+    /**
+     * @param cmd
+     * @param args
+     * @param id
+     */
+    private def getParamOrNull(cmd: Command, args: Seq[Argument], id: String): String =
+        args.find(_.parameter.id == id) match {
+            case Some(arg) ⇒ stripQuotes(arg.value.get)
+            case None ⇒ null
+        }
+
+    /**
+     *
+     * @param cmd
+     * @param args
+     * @param id
+     * @return
+     */
+    private def getFlagParam(cmd: Command, args: Seq[Argument], id: String, dflt: Boolean): Boolean =
+        args.find(_.parameter.id == id) match {
+            case Some(b) ⇒ true
+            case None ⇒ dflt
+        }
+
+    /**
+     *
+     * @param cmd
+     * @param args
+     * @param id
+     * @return
+     */
+    private def getCpParam(cmd: Command, args: Seq[Argument], id: String): String =
+        getParamOpt(cmd, args, id) match {
+            case Some(path) ⇒ normalizeCp(stripQuotes(path))
+            case None ⇒ null
+        }
+
+    /**
+     *
+     * @param cmd
+     * @param args
+     * @param id
+     * @return
+     */
+    private def getPathParam(cmd: Command, args: Seq[Argument], id: String): String =
+        getParamOpt(cmd, args, id) match {
+            case Some(path) ⇒
+                val normPath = refinePath(stripQuotes(path))
+
+                checkFilePath(normPath)
+
+                normPath
+
+            case None ⇒ null
+        }
+
+    /**
+     *
+     * @param path
+     */
+    private def refinePath(path: String): String = {
+        require(path != null)
+
+        if (path.nonEmpty && path.head == '~') new File(SystemUtils.getUserHome, path.tail).getAbsolutePath else path
+    }
+
+    /**
      *
      * @param s
      * @return
@@ -286,6 +406,59 @@ object NCCli extends App {
 
     /**
      *
+     * @param path
+     */
+    private def checkFilePath(path: String): Unit = {
+        val file = new File(path)
+
+        if (!file.exists() || !file.isFile)
+            throw new IllegalArgumentException(s"File not found: ${c(file.getAbsolutePath)}")
+    }
+
+    /**
+     * Checks whether given list of models contains class names outside of NLPCraft project.
+     *
+     * @param mdls Comma-separated list of fully qualified class names for data models.
+     * @return
+     */
+    private def hasExternalModels(mdls: String): Boolean =
+        U.splitTrimFilter(mdls, ",").exists(!_.startsWith("org.apache.nlpcraft."))
+
+    /**
+     * Handles tilda and checks that every component of the given class path exists relative to the current user working
+     * directory of this process.
+     *
+     * @param cp Classpath to normalize.
+     * @return
+     */
+    private def normalizeCp(cp: String): String =
+        U.splitTrimFilter(cp, CP_WIN_NIX_SEPS).map(refinePath).map(path ⇒ {
+            val normPath = refinePath(path)
+
+            if (!normPath.contains("*") && !new File(normPath).exists())
+                throw new IllegalStateException(s"Classpath not found: ${c(path)}")
+            else
+                normPath
+        })
+        .mkString(CP_SEP)
+
+    /**
+     *
+     */
+    private def cleanUpTempFiles(): Unit = {
+        val tstamp = currentTime - 1000 * 60 * 60 * 24 * 2 // 2 days ago.
+
+        for (file <- new File(SystemUtils.getUserHome, ".nlpcraft").listFiles())
+            if (file.lastModified() < tstamp) {
+                val name = file.getName
+
+                if (name.startsWith("server_log") || name.startsWith("server_log") || name.startsWith(".pid_"))
+                    file.delete()
+            }
+    }
+
+    /**
+     *
      * @param endpoint
      * @return
      */
@@ -294,15 +467,16 @@ object NCCli extends App {
 
     /**
      *
-     * @param pathOpt
+     * @param cmd Command descriptor.
+     * @param args Arguments, if any, for this command.
+     * @param repl Whether or not executing from REPL.
      */
-    private def checkFilePath(pathOpt: Option[Argument]): Unit =
-        if (pathOpt.isDefined) {
-            val file = new File(stripQuotes(pathOpt.get.value.get))
+    private [cmdline] def cmdRest(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
+        val restPath = getParam(cmd, args, "path") // REST call path (NOT a file system path).
+        val json = stripQuotes(getParam(cmd, args, "json"))
 
-            if (!file.exists() || !file.isFile)
-                throw new IllegalArgumentException(s"File not found: ${c(file.getAbsolutePath)}")
-        }
+        httpRest(cmd, restPath, json)
+    }
 
     /**
      * @param cmd  Command descriptor.
@@ -310,27 +484,15 @@ object NCCli extends App {
      * @param repl Whether or not running from REPL.
      */
     private [cmdline] def cmdStartServer(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
-        val cfgPath = args.find(_.parameter.id == "config")
-        val igniteCfgPath = args.find(_.parameter.id == "igniteConfig")
-        val noWait = args.exists(_.parameter.id == "noWait")
-        val timeoutMins = args.find(_.parameter.id == "timeoutMins") match {
-            case Some(arg) ⇒
-                try
-                    Integer.parseInt(arg.value.get)
-                catch {
-                    case _: Exception ⇒ throw InvalidParameter(cmd, "timeoutMins")
-                }
-
-            case None ⇒ 2 // Default.
-        }
-        val jvmOpts = args.find(_.parameter.id == "jvmopts") match {
-            case Some(arg) ⇒ U.splitTrimFilter(stripQuotes(arg.value.get), " ")
+        val cfgPath = getPathParam(cmd, args, "config")
+        val igniteCfgPath = getPathParam(cmd, args, "igniteConfig")
+        val noWait = getFlagParam(cmd, args, "noWait", false)
+        val timeoutMins = getIntParam(cmd, args, "timeoutMins", 2)
+        val jvmOpts = getParamOpt(cmd, args, "jvmopts") match {
+            case Some(opts) ⇒ U.splitTrimFilter(stripQuotes(opts), " ")
             case None ⇒ Seq("-ea", "-Xms2048m", "-XX:+UseG1GC")
         }
 
-        checkFilePath(cfgPath)
-        checkFilePath(igniteCfgPath)
-
         // Ensure that there isn't another local server running.
         loadServerBeacon() match {
             case Some(b) ⇒ throw new IllegalStateException(
@@ -367,22 +529,15 @@ object NCCli extends App {
         srvArgs += JAVA_CP
         srvArgs += "org.apache.nlpcraft.NCStart"
         srvArgs += "-server"
-        srvArgs += (
-            cfgPath match {
-                case Some(path) ⇒ s"-config=${stripQuotes(path.value.get)}"
-                case None ⇒ ""
-            }
-        )
-        srvArgs += (
-            igniteCfgPath match {
-                case Some(path) ⇒ s"-igniteConfig=${stripQuotes(path.value.get)}"
-                case None ⇒ ""
-            }
-        )
+
+        if (cfgPath != null)
+            srvArgs += s"-config=$cfgPath"
+        if (igniteCfgPath != null)
+            srvArgs += s"-igniteConfig=$igniteCfgPath"
 
         val srvPb = new ProcessBuilder(srvArgs.asJava)
 
-        srvPb.directory(new File(WORK_DIR))
+        srvPb.directory(new File(USR_WORK_DIR))
         srvPb.redirectErrorStream(true)
 
         val bleachPb = new ProcessBuilder(
@@ -393,7 +548,7 @@ object NCCli extends App {
             "org.apache.nlpcraft.model.tools.cmdline.NCCliAnsiBleach"
         )
 
-        bleachPb.directory(new File(WORK_DIR))
+        bleachPb.directory(new File(USR_WORK_DIR))
         bleachPb.redirectOutput(Redirect.appendTo(output))
 
         try {
@@ -417,9 +572,7 @@ object NCCli extends App {
                 val tbl = new NCAsciiTable()
 
                 tbl += (s"${g("stop-server")}", "Stop the server.")
-                tbl += (s"${g("start-probe")}", "Start the probe.")
-                tbl += (s"${g("stop-probe")}", "Stop the probe.")
-                tbl += (s"${g("info")}", "Get server & probe information.")
+                tbl += (s"${g("info-server")}", "Get server information.")
                 tbl += (s"${g("ping-server")}", "Ping the server.")
                 tbl += (s"${g("tail-server")}", "Tail the server log.")
 
@@ -524,42 +677,6 @@ object NCCli extends App {
     }
 
     /**
-     * Checks whether given list of models contains class names outside of NLPCraft project.
-     *
-     * @param mdls Comma-separated list of fully qualified class names for data models.
-     * @return
-     */
-    private def hasExternalModels(mdls: String): Boolean =
-        U.splitTrimFilter(mdls, ",").exists(!_.startsWith("org.apache.nlpcraft."))
-
-    /**
-     * Checks that every component of the given class path exists relative to the current user working
-     * directory of this process.
-     *
-     * @param cp Classpath to check.
-     * @return
-     */
-    private def checkClasspath(cp: String): Unit =
-        for (path <- U.splitTrimFilter(cp, ";:"))
-            if (!new File(path).exists())
-                throw new IllegalStateException(s"Classpath not found: ${c(path)}")
-
-    /**
-     *
-     */
-    private def cleanUpTempFiles(): Unit = {
-        val tstamp = currentTime - 1000 * 60 * 60 * 24 * 2 // 2 days ago.
-
-        for (file <- new File(SystemUtils.getUserHome, ".nlpcraft").listFiles())
-            if (file.lastModified() < tstamp) {
-                val name = file.getName
-
-                if (name.startsWith("server_log") || name.startsWith("server_log") || name.startsWith(".pid_"))
-                    file.delete()
-            }
-    }
-
-    /**
      * @param cmd  Command descriptor.
      * @param args Arguments, if any, for this command.
      * @param repl Whether or not running from REPL.
@@ -569,22 +686,16 @@ object NCCli extends App {
         if (loadServerBeacon().isEmpty)
             throw NoLocalServer()
 
-        val cfgPath = args.find(_.parameter.id == "config")
-        val addCp = args.find(_.parameter.id == "cp") match {
-            case Some(cp) ⇒ cp.value.get
-            case None ⇒ null
-        }
-        val mdls = args.find(_.parameter.id == "models") match {
-            case Some(arg) ⇒ stripQuotes(arg.value.get)
-            case None ⇒ null
-        }
-        val jvmOpts = args.find(_.parameter.id == "jvmopts") match {
-            case Some(arg) ⇒ U.splitTrimFilter(stripQuotes(arg.value.get), " ")
+        val cfgPath = getPathParam(cmd, args, "config")
+        val addCp = getCpParam(cmd, args, "cp")
+        val mdls = getParamOrNull(cmd, args, "models")
+        val jvmOpts = getParamOpt(cmd, args, "jvmopts") match {
+            case Some(opts) ⇒ U.splitTrimFilter(stripQuotes(opts), " ")
             case None ⇒ Seq("-ea", "-Xms1024m")
         }
 
         if (mdls != null) {
-            if (hasExternalModels(mdls) && addCp == null)
+            if (hasExternalModels(mdls) && addCp != null)
                 throw new IllegalStateException(
                     s"Additional classpath is required when deploying your own models. " +
                     s"Use ${c("--cp")} parameters to provide additional classpath.")
@@ -593,31 +704,29 @@ object NCCli extends App {
         if (mdls == null && addCp != null)
             warn(s"Additional classpath (${c("--cp")}) but no models (${c("--models")}).")
 
-        if (addCp != null)
-            checkClasspath(addCp)
-
-        checkFilePath(cfgPath)
-
-        val sep = System.getProperty("path.separator")
-
         var validatorArgs = mutable.ArrayBuffer.empty[String]
 
         validatorArgs += JAVA
         validatorArgs ++= jvmOpts
 
-        if (cfgPath.isDefined)
-            validatorArgs += s"-DNLPCRAFT_PROBE_CONFIG=${cfgPath.get}"
+        if (cfgPath != null)
+            validatorArgs += s"-DNLPCRAFT_PROBE_CONFIG=$cfgPath"
 
         if (mdls != null)
             validatorArgs += s"-DNLPCRAFT_TEST_MODELS=$mdls"
 
         validatorArgs += "-cp"
-        validatorArgs += (if (addCp == null) JAVA_CP else s"$JAVA_CP$sep$addCp".replace(s"$sep$sep", sep))
+
+        if (addCp != null)
+            validatorArgs += s"$JAVA_CP$CP_SEP$addCp".replace(s"$CP_SEP$CP_SEP", CP_SEP)
+        else
+            validatorArgs += JAVA_CP
+
         validatorArgs += "org.apache.nlpcraft.model.tools.test.NCTestAutoModelValidator"
 
         val validatorPb = new ProcessBuilder(validatorArgs.asJava)
 
-        validatorPb.directory(new File(WORK_DIR))
+        validatorPb.directory(new File(USR_WORK_DIR))
         validatorPb.inheritIO()
 
         try {
@@ -641,28 +750,22 @@ object NCCli extends App {
         if (loadServerBeacon().isEmpty)
             throw NoLocalServer()
 
-        val cfgPath = args.find(_.parameter.id == "config")
-        val noWait = args.exists(_.parameter.id == "noWait")
-        val addCp = args.find(_.parameter.id == "cp") match {
-            case Some(cp) ⇒ cp.value.get
-            case None ⇒ null
+        // Ensure that there isn't another local probe running.
+        loadProbeBeacon() match {
+            case Some(b) ⇒ throw new IllegalStateException(
+                s"Existing probe (pid ${c(b.pid)}) detected. " +
+                s"Use ${c("'stop-probe'")} command to stop it, if necessary."
+            )
+            case None ⇒ ()
         }
-        val timeoutMins = args.find(_.parameter.id == "timeoutMins") match {
-            case Some(arg) ⇒
-                try
-                    Integer.parseInt(arg.value.get)
-                catch {
-                    case _: Exception ⇒ throw InvalidParameter(cmd, "timeoutMins")
-                }
 
-            case None ⇒ 1 // Default.
-        }
-        val mdls = args.find(_.parameter.id == "models") match {
-            case Some(arg) ⇒ stripQuotes(arg.value.get)
-            case None ⇒ null
-        }
-        val jvmOpts = args.find(_.parameter.id == "jvmopts") match {
-            case Some(arg) ⇒ U.splitTrimFilter(stripQuotes(arg.value.get), " ")
+        val cfgPath = getPathParam(cmd, args, "config")
+        val noWait = getFlagParam(cmd, args, "noWait", false)
+        val addCp = getCpParam(cmd, args, "cp")
+        val timeoutMins = getIntParam(cmd, args, "timeoutMins", 1)
+        val mdls = getParamOrNull(cmd, args, "models")
+        val jvmOpts = getParamOpt(cmd, args, "jvmopts") match {
+            case Some(opts) ⇒ U.splitTrimFilter(stripQuotes(opts), " ")
             case None ⇒ Seq("-ea", "-Xms1024m")
         }
 
@@ -676,20 +779,6 @@ object NCCli extends App {
         if (mdls == null && addCp != null)
             warn(s"Additional classpath (${c("--cp")}) but no models (${c("--models")}).")
 
-        if (addCp != null)
-            checkClasspath(addCp)
-
-        checkFilePath(cfgPath)
-
-        // Ensure that there isn't another local probe running.
-        loadProbeBeacon() match {
-            case Some(b) ⇒ throw new IllegalStateException(
-                s"Existing probe (pid ${c(b.pid)}) detected. " +
-                s"Use ${c("'stop-probe'")} command to stop it, if necessary."
-            )
-            case None ⇒ ()
-        }
-
         val logTstamp = currentTime
 
         // Server log redirect.
@@ -698,8 +787,6 @@ object NCCli extends App {
         // Store in REPL state right away.
         state.probeLog = Some(output)
 
-        val sep = System.getProperty("path.separator")
-
         var prbArgs = mutable.ArrayBuffer.empty[String]
 
         prbArgs += JAVA
@@ -710,22 +797,19 @@ object NCCli extends App {
             prbArgs += "-Dconfig.override_with_env_vars=true"
 
         prbArgs += "-cp"
-        prbArgs += (if (addCp == null) JAVA_CP else s"$JAVA_CP$sep$addCp".replace(s"$sep$sep", sep))
+        prbArgs += (if (addCp == null) JAVA_CP else s"$JAVA_CP$CP_SEP$addCp".replace(s"$CP_SEP$CP_SEP", CP_SEP))
         prbArgs += "org.apache.nlpcraft.NCStart"
         prbArgs += "-probe"
-        prbArgs += (
-            cfgPath match {
-                case Some(path) ⇒ s"-config=${stripQuotes(path.value.get)}"
-                case None ⇒ ""
-            }
-        )
+
+        if (cfgPath != null)
+            prbArgs += s"-config=$cfgPath"
 
         val prbPb = new ProcessBuilder(prbArgs.asJava)
 
         if (mdls != null)
             prbPb.environment().put("CONFIG_FORCE_nlpcraft_probe_models", mdls)
 
-        prbPb.directory(new File(WORK_DIR))
+        prbPb.directory(new File(USR_WORK_DIR))
         prbPb.redirectErrorStream(true)
 
         val bleachPb = new ProcessBuilder(
@@ -736,7 +820,7 @@ object NCCli extends App {
             "org.apache.nlpcraft.model.tools.cmdline.NCCliAnsiBleach"
         )
 
-        bleachPb.directory(new File(WORK_DIR))
+        bleachPb.directory(new File(USR_WORK_DIR))
         bleachPb.redirectOutput(Redirect.appendTo(output))
 
         try {
@@ -892,16 +976,7 @@ object NCCli extends App {
      * @param repl Whether or not executing from REPL.
      */
     private [cmdline] def cmdTailServer(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
-        val lines = args.find(_.parameter.id == "lines") match {
-            case Some(arg) ⇒
-                try
-                    Integer.parseInt(arg.value.get)
-                catch {
-                    case _: Exception ⇒ throw InvalidParameter(cmd, "lines")
-                }
-
-            case None ⇒ 20 // Default.
-        }
+        val lines = getIntParam(cmd, args, "lines", 20)
 
         if (lines <= 0)
             throw InvalidParameter(cmd, "lines")
@@ -918,16 +993,7 @@ object NCCli extends App {
      * @param repl Whether or not executing from REPL.
      */
     private [cmdline] def cmdTailProbe(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
-        val lines = args.find(_.parameter.id == "lines") match {
-            case Some(arg) ⇒
-                try
-                    Integer.parseInt(arg.value.get)
-                catch {
-                    case _: Exception ⇒ throw InvalidParameter(cmd, "lines")
-                }
-
-            case None ⇒ 20 // Default.
-        }
+        val lines = getIntParam(cmd, args, "lines", 20)
 
         if (lines <= 0)
             throw InvalidParameter(cmd, "lines")
@@ -944,21 +1010,12 @@ object NCCli extends App {
      * @param repl Whether or not executing from REPL.
      */
     private [cmdline] def cmdPingServer(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
-        val endpoint = getRestEndpointFromBeacon
-
-        val num = args.find(_.parameter.id == "number") match {
-            case Some(arg) ⇒
-                try
-                    Integer.parseInt(arg.value.get)
-                catch {
-                    case _: Exception ⇒ throw InvalidParameter(cmd, "number")
-                }
-
-            case None ⇒ 1 // Default.
-        }
+        val num = getIntParam(cmd, args, "number", 1)
 
         var i = 0
 
+        val endpoint = getRestEndpointFromBeacon
+
         while (i < num) {
             log(s"(${i + 1} of $num) pinging server at ${b(endpoint)} ")
 
@@ -999,7 +1056,7 @@ object NCCli extends App {
             i += 1
 
             if (i < num)
-            // Pause between pings.
+                // Pause between pings.
                 Thread.sleep(500.ms)
         }
     }
@@ -1603,8 +1660,8 @@ object NCCli extends App {
     private [cmdline] def cmdSignIn(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
         state.accessToken match {
             case None ⇒
-                val email = args.find(_.parameter.id == "email").flatMap(_.value).getOrElse(DFLT_USER_EMAIL)
-                val passwd = args.find(_.parameter.id == "passwd").flatMap(_.value).getOrElse(DFLT_USER_PASSWD)
+                val email = getParam(cmd, args, "email", DFLT_USER_EMAIL)
+                val passwd = getParam(cmd, args, "passwd", DFLT_USER_PASSWD)
 
                 httpRest(
                     cmd,
@@ -1691,8 +1748,8 @@ object NCCli extends App {
     private [cmdline] def cmdSugSyn(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
         state.accessToken match {
             case Some(acsTok) ⇒
-                val mdlId = args.find(_.parameter.id == "mdlId").flatMap(_.value).getOrElse(throw MissingParameter(cmd, "mdlId"))
-                val minScore = Try(args.find(_.parameter.id == "minScore").flatMap(_.value).getOrElse("0.5").toFloat).getOrElse(throw InvalidParameter(cmd, "minScore"))
+                val mdlId = getParam(cmd, args, "mdlId")
+                val minScore = getDoubleParam(cmd, args, "minScore", 0.5)
 
                 httpRest(
                     cmd,
@@ -1718,10 +1775,10 @@ object NCCli extends App {
     private [cmdline] def cmdAsk(cmd: Command, args: Seq[Argument], repl: Boolean): Unit =
         state.accessToken match {
             case Some(acsTok) ⇒
-                val mdlId = args.find(_.parameter.id == "mdlId").flatMap(_.value).getOrElse(throw MissingParameter(cmd, "mdlId"))
-                val txt = args.find(_.parameter.id == "txt").flatMap(_.value).getOrElse(throw MissingParameter(cmd, "txt"))
-                val data = args.find(_.parameter.id == "data").flatMap(_.value).orNull
-                val enableLog = args.find(_.parameter.id == "enableLog").flatMap(_.value).getOrElse(false)
+                val mdlId = getParam(cmd, args, "mdlId")
+                val txt = getParam(cmd, args, "txt")
+                val data = getParamOrNull(cmd, args, "data")
+                val enableLog = getFlagParam(cmd, args, "enableLog", false)
 
                 httpRest(
                     cmd,
@@ -1792,46 +1849,6 @@ object NCCli extends App {
     }
 
     /**
-     *
-     * @param cmd Command descriptor.
-     * @param args Arguments, if any, for this command.
-     * @param repl Whether or not executing from REPL.
-     */
-    private [cmdline] def cmdRest(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
-        val path = args.find(_.parameter.id == "path").getOrElse(throw MissingParameter(cmd, "path")).value.get
-        val json = stripQuotes(args.find(_.parameter.id == "json").getOrElse(throw MissingParameter(cmd, "json")).value.get)
-
-        httpRest(cmd, path, json)
-    }
-
-    /**
-      * @param cmd
-      * @param args
-      * @param id
-      * @param dflt
-      */
-    @throws[MissingParameter]
-    private def get(cmd: Command, args: Seq[Argument], id: String, dflt: String = null): String =
-        args.find(_.parameter.id == id).flatMap(_.value) match {
-            case Some(v) ⇒ v
-            case None ⇒
-                if (dflt == null)
-                    throw MissingParameter(cmd, id)
-
-                dflt
-        }
-
-    /**
-      *
-      * @param path
-      */
-    private def refinePath(path: String): String = {
-        require(path != null)
-
-        if (path.nonEmpty && path.head == '~') new File(SystemUtils.getUserHome, path.tail).getAbsolutePath else path
-    }
-
-    /**
       *
       * @param cmd
       * @param name
@@ -1980,9 +1997,9 @@ object NCCli extends App {
       * @param repl Whether or not executing from REPL.
       */
     private [cmdline] def cmdGenModel(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
-        val filePath = refinePath(get(cmd, args, "filePath"))
-        val overrideFlag = get(cmd, args,"override", "false").toLowerCase
-        val modelId = get(cmd, args,"modelId")
+        val filePath = refinePath(getParam(cmd, args, "filePath"))
+        val overrideFlag = getParam(cmd, args,"override", "false").toLowerCase
+        val mdlId = getParam(cmd, args,"mdlId")
 
         checkSupported(cmd,"overrideFlag", overrideFlag, "true", "false")
 
@@ -2017,7 +2034,7 @@ object NCCli extends App {
             s"src/main/resources/template_model.$fileExt",
             out.getName,
             Some(extractHdr),
-            "templateModelId" → modelId
+            "templateModelId" → mdlId
         )
 
         logln(s"Model file stub created: ${c(out.getCanonicalPath)}")
@@ -2030,13 +2047,13 @@ object NCCli extends App {
       * @param repl Whether or not executing from REPL.
       */
     private [cmdline] def cmdGenProject(cmd: Command, args: Seq[Argument], repl: Boolean): Unit = {
-        val outputDir = refinePath(get(cmd, args, "outputDir", "."))
-        val baseName = get(cmd, args,"baseName")
-        val lang = get(cmd, args,"lang", "java").toLowerCase
-        val buildTool = get(cmd, args,"buildTool", "mvn").toLowerCase
-        val pkgName = get(cmd, args,"packageName", "org.apache.nlpcraft.demo").toLowerCase
-        val fileType = get(cmd, args,"modelType", "yaml").toLowerCase
-        val overrideFlag = get(cmd, args,"override", "false").toLowerCase
+        val outputDir = refinePath(getParam(cmd, args, "outputDir", "."))
+        val baseName = getParam(cmd, args,"baseName")
+        val lang = getParam(cmd, args,"lang", "java").toLowerCase
+        val buildTool = getParam(cmd, args,"buildTool", "mvn").toLowerCase
+        val pkgName = getParam(cmd, args,"packageName", "org.apache.nlpcraft.demo").toLowerCase
+        val fileType = getParam(cmd, args,"modelType", "yaml").toLowerCase
+        val overrideFlag = getParam(cmd, args,"override", "false").toLowerCase
         val dst = new File(outputDir, baseName)
         val pkgDir = pkgName.replaceAll("\\.", "/")
         val clsName = s"${baseName.head.toUpper}${baseName.tail}"
@@ -2537,7 +2554,7 @@ object NCCli extends App {
                 val prompt1 = if (state.isServerOnline) gb(k(s" server: ${BO}ON$RST$GB ")) else rb(w(s" server: ${BO}OFF$RST$RB "))
                 val prompt2 = if (state.isProbeOnline) gb(k(s" probe: ${BO}ON$RST$GB ")) else rb(w(s" probe: ${BO}OFF$RST$RB "))
                 val prompt3 = wb(k(s" acsTok: $acsTokStr")) // Access token, if any.
-                val prompt4 = kb(g(s" $WORK_DIR ")) // Current working directory.
+                val prompt4 = kb(g(s" $USR_WORK_DIR ")) // Current working directory.
 
                 if (!wasLastLineEmpty)
                     reader.printAbove("\n" + prompt1 + ":" + prompt2 + ":" + prompt3 + ":" + prompt4)
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliCommands.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliCommands.scala
index 9ccdce8..2d2b216 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliCommands.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/cmdline/NCCliCommands.scala
@@ -124,8 +124,8 @@ private [cmdline] object NCCliCommands {
                     value = Some("'json'"),
                     desc =
                         s"REST call parameters as JSON object. Since standard JSON only supports double " +
-                        s"quotes the entire JSON string should be enclosed in single quotes. You can " +
-                        s"find full OpenAPI specification for NLPCraft REST API at " +
+                        s"quotes the entire JSON string should be enclosed in single quotes. Note that on Windows you " +
+                        s"need to escape double quotes. You can find full OpenAPI specification for NLPCraft REST API at " +
                         s"https://nlpcraft.apache.org/using-rest.html"
                 )
             ),
@@ -141,8 +141,8 @@ private [cmdline] object NCCliCommands {
                 Example(
                     usage = Seq(
                         s"> nlpcraft.cmd rest ",
-                        "  -p=signin",
-                        "  -j='{\\\"email\\\": \\\"admin@admin.com\\\", \\\"passwd\\\": \\\"admin\\\"}'"
+                        "  --path=signin",
+                        "  --json='{\\\"email\\\": \\\"admin@admin.com\\\", \\\"passwd\\\": \\\"admin\\\"}'"
                     ),
                     desc =
                         s"${bo("Windows:")} issues ${y("'signin'")} REST call with given JSON payload. " +
@@ -156,8 +156,8 @@ private [cmdline] object NCCliCommands {
             synopsis = s"Wrapper for ${c("'/signin'")} REST call.",
             desc = Some(
                 s"If no arguments provided, it signs in with the " +
-                    s"default 'admin@admin.com' user account. NOTE: please make sure to remove this account when " +
-                    s"running in production."
+                s"default 'admin@admin.com' user account. NOTE: please make sure to remove this account when " +
+                s"running in production."
             ),
             body = NCCli.cmdSignIn,
             params = Seq(
@@ -167,12 +167,12 @@ private [cmdline] object NCCliCommands {
                     value = Some("email"),
                     optional = true,
                     desc =
-                        s"Email of the user. If not provided, 'admin@admin.com' will be used."
+                        s"Email of the user. If not provided, default 'admin@admin.com' email will be used."
                 ),
                 Parameter(
                     id = "passwd",
                     names = Seq("--passwd", "-p"),
-                    value = Some("****"),
+                    value = Some("password"),
                     optional = true,
                     desc =
                         s"User password to sign in. If not provided, the default password will be used."
@@ -210,9 +210,9 @@ private [cmdline] object NCCliCommands {
             synopsis = s"REST call in a convenient way for REPL mode.",
             desc = Some(
                 s"When using this command you supply all call parameters separately through their own parameters named " +
-                    s"after their corresponding parameters in REST specification. " +
-                    s"In REPL mode, hit ${rv(" Tab ")} to see auto-suggestion and " +
-                    s"auto-completion candidates for commonly used paths and call parameters."
+                s"after their corresponding parameters in REST specification. " +
+                s"In REPL mode, hit ${rv(" Tab ")} to see auto-suggestion and " +
+                s"auto-completion candidates for commonly used paths and call parameters."
             ),
             body = NCCli.cmdCall,
             params = Seq(
@@ -236,7 +236,7 @@ private [cmdline] object NCCliCommands {
                         s"${y("'xxx'")} name corresponds to the REST call parameter that can be found at https://nlpcraft.apache.org/using-rest.html " +
                         s"The value of this parameter should be a valid JSON value using valid JSON syntax. Note that strings " +
                         s"don't have to be in double quotes. JSON objects and arrays should be specified as a JSON string in single quotes. You can have " +
-                        s"as many ${y("'--xxx=value'")} parameters as requires by the ${y("'--path'")} parameter. " +
+                        s"as many ${y("'--xxx=value'")} parameters as requires by the ${y("'--path'")} parameter. Note that on Windows you need to escape double quotes. " +
                         s"In REPL mode, hit ${rv(" Tab ")} to see auto-suggestion for possible parameters and their values."
                 )
             ),
@@ -293,7 +293,7 @@ private [cmdline] object NCCliCommands {
             params = Seq(
                 Parameter(
                     id = "mdlId",
-                    names = Seq("--mdlId"),
+                    names = Seq("--mdlId", "-m"),
                     value = Some("model.id"),
                     desc =
                         s"ID of the data model to send the request to. " +
@@ -301,24 +301,23 @@ private [cmdline] object NCCliCommands {
                 ),
                 Parameter(
                     id = "txt",
-                    names = Seq("--txt"),
+                    names = Seq("--txt", "-t"),
                     value = Some("txt"),
                     desc =
                         s"Text of the question."
                 ),
                 Parameter(
                     id = "data",
-                    names = Seq("--data"),
+                    names = Seq("--data", "-d"),
                     value = Some("'{}'"),
                     optional = true,
                     desc = s"Additional JSON data with maximum JSON length of 512000 bytes. Default is ${c("'null'")}."
                 ),
                 Parameter(
                     id = "enableLog",
-                    names = Seq("--enableLog"),
-                    value = Some("true|false"),
+                    names = Seq("--enableLog", "-l"),
                     optional = true,
-                    desc = s"Flag to enable detailed processing log to be returned with the result. Default is ${c("'false'")}."
+                    desc = s"Enable detailed processing log to be returned with the result."
                 )
             ),
             examples = Seq(
@@ -389,21 +388,21 @@ private [cmdline] object NCCliCommands {
                 ),
                 Parameter(
                     id = "modelId",
-                    names = Seq("--model-id", "-x"),
+                    names = Seq("--mdlId", "-m"),
                     value = Some("id"),
                     optional = true,
                     desc = s"Generated model ID. By default, the model ID is ${c("'sql.model.id'")}."
                 ),
                 Parameter(
                     id = "modelVer",
-                    names = Seq("--model-ver", "-v"),
+                    names = Seq("--mdlVer", "-v"),
                     value = Some("version"),
                     optional = true,
                     desc = s"Generated model version. By default, the model version is ${c("'1.0.0-timestamp'")}."
                 ),
                 Parameter(
                     id = "modelName",
-                    names = Seq("--model-name", "-n"),
+                    names = Seq("--mdlName", "-n"),
                     value = Some("name"),
                     optional = true,
                     desc = s"Generated model name. By default, the model name is ${c("'SQL-based-model'")}."
@@ -476,7 +475,7 @@ private [cmdline] object NCCliCommands {
                     optional = true,
                     desc =
                         s"Gets extended help and usage information for the ${c("'gen-sql'")} command. " +
-                        s"Includes information on how to run this tool standalone."
+                        s"Includes information on how to run this tool standalone in a separate process."
                 )
             ),
             examples = Seq(
@@ -490,16 +489,16 @@ private [cmdline] object NCCliCommands {
                 Example(
                     usage = Seq(
                         s"$PROMPT $SCRIPT_NAME gen-sql",
-                        "  --url=jdbc:postgresql://localhost:5432/mydb",
-                        "  --driver=org.postgresql.Driver",
+                          "  --url=jdbc:postgresql://localhost:5432/mydb",
+                          "  --driver=org.postgresql.Driver",
                         """  --prefix="tbl_, col_"""",
                         """  --suffix="_tmp, _old, _unused"""",
-                        "  --schema=public",
+                          "  --schema=public",
                         """  --exclude="#_.+"""",
-                        "  --out=model.json"
+                          "  --out=model.json"
                     ),
                     desc =
-                        s"Generates model stub from given SQL database connection."
+                        s"Generates ${c("'model.json'")} model stub from given SQL database connection."
                 )
             )
         ),
@@ -512,13 +511,14 @@ private [cmdline] object NCCliCommands {
                 s"it requires user to be signed in. REPL session keeps the currently active access " +
                 s"token after user signed in. For command line mode, use ${c("'rest'")} command with " +
                 s"corresponding parameters. Note also that it requires a local probe running that hosts " +
-                s"the specified model. Find more information about this tool at https://nlpcraft.apache.org/tools/syn_tool.html"
+                s"the specified model as well as running ${c("'ctxword'")} server. Find more information about " +
+                s"this tool at https://nlpcraft.apache.org/tools/syn_tool.html"
             ),
             body = NCCli.cmdSugSyn,
             params = Seq(
                 Parameter(
                     id = "mdlId",
-                    names = Seq("--mdlId"),
+                    names = Seq("--mdlId", "-m"),
                     value = Some("model.id"),
                     desc =
                         s"ID of the model to run synonym suggestion on. " +
@@ -527,7 +527,7 @@ private [cmdline] object NCCliCommands {
                 ),
                 Parameter(
                     id = "minScore",
-                    names = Seq("--minScore"),
+                    names = Seq("--minScore", "-s"),
                     value = Some("0.5"),
                     optional = true,
                     desc = s"Minimal score to include into the result (from 0 to 1). Default is ${c("0.5")}."
@@ -536,7 +536,7 @@ private [cmdline] object NCCliCommands {
             examples = Seq(
                 Example(
                     usage = Seq(
-                        s"""> sugsyn --mdlId=my.model.id"""
+                        s"""> sugsyn -m=my.model.id"""
                     ),
                     desc =
                         s"Issues ${y("'model/sugsyn'")} REST call with default min score and given model ID."
@@ -555,7 +555,7 @@ private [cmdline] object NCCliCommands {
                 Parameter(
                     id = "lines",
                     names = Seq("--lines", "-l"),
-                    value = Some("num"),
+                    value = Some("20"),
                     desc =
                         s"Number of the server log lines from the end to display. Default is 20."
                 )
@@ -579,7 +579,7 @@ private [cmdline] object NCCliCommands {
                 Parameter(
                     id = "lines",
                     names = Seq("--lines", "-l"),
-                    value = Some("num"),
+                    value = Some("20"),
                     desc =
                         s"Number of the probe log lines from the end to display. Default is 20."
                 )
@@ -597,24 +597,25 @@ private [cmdline] object NCCliCommands {
             synopsis = s"Starts local server.",
             desc = Some(
                 s"Server is started in the external JVM process with both stdout and stderr piped out into log file. " +
-                s"Command will block until the server is started unless ${y("'--no-wait'")} parameter is used or timeout is expired."
+                s"Command will block until the server is started unless ${y("'--noWait'")} parameter is used or timeout is expired."
             ),
             body = NCCli.cmdStartServer,
             params = Seq(
                 Parameter(
                     id = "config",
-                    names = Seq("--config", "-c"),
+                    names = Seq("--cfg", "-c"),
                     value = Some("path"),
                     optional = true,
                     desc =
                         s"Configuration file path. Server will automatically look for ${y("'nlpcraft.conf'")} " +
                         s"configuration file in the same directory as NLPCraft JAR file. If the configuration file has " +
                         s"different name or in different location use this parameter to provide an alternative path. " +
-                        s"Note that the server and the probe can use the same file for their configuration."
+                        s"Note that the server and the probe can use the same file for their configuration. " +
+                        s"Note also that you can use ${c("'~'")} at the beginning of the path to specify user home directory."
                 ),
                 Parameter(
                     id = "igniteConfig",
-                    names = Seq("--ignite-config", "-i"),
+                    names = Seq("--igniteCfg", "-i"),
                     value = Some("path"),
                     optional = true,
                     desc =
@@ -622,11 +623,12 @@ private [cmdline] object NCCliCommands {
                         s"computing plane and a default distributed storage. Server will automatically look for " +
                         s"${y("'ignite.xml'")} configuration file in the same directory as NLPCraft JAR file. If the " +
                         s"configuration file has different name or in different location use this parameter to " +
-                        s"provide an alternative path."
+                        s"provide an alternative path. " +
+                        s"Note also that you can use ${c("'~'")} at the beginning of the path to specify user home directory."
                 ),
                 Parameter(
                     id = "jvmopts",
-                    names = Seq("--jvm-opts", "-j"),
+                    names = Seq("--jvmOpts", "-j"),
                     value = Some("<jvm flags>"),
                     optional = true,
                     desc =
@@ -635,14 +637,14 @@ private [cmdline] object NCCliCommands {
                 ),
                 Parameter(
                     id = "noWait",
-                    names = Seq("--no-wait"),
+                    names = Seq("--noWait"),
                     optional = true,
                     desc =
                         s"Instructs command not to wait for the server startup and return immediately."
                 ),
                 Parameter(
                     id = "timeoutMins",
-                    names = Seq("--timeout-mins", "-t"),
+                    names = Seq("--timeoutMins", "-t"),
                     optional = true,
                     value = Some("3"),
                     desc =
@@ -655,7 +657,7 @@ private [cmdline] object NCCliCommands {
                     desc = "Starts local server with default configuration."
                 ),
                 Example(
-                    usage = Seq(s"$PROMPT $SCRIPT_NAME start-server -c=/opt/nlpcraft/nlpcraft.conf -t=5"),
+                    usage = Seq(s"$PROMPT $SCRIPT_NAME start-server -c=~/myapp/nlpcraft.conf -t=5"),
                     desc = "Starts local server with alternative configuration file and timeout of 5 mins."
                 )
             )
@@ -666,20 +668,21 @@ private [cmdline] object NCCliCommands {
             synopsis = s"Starts local probe.",
             desc = Some(
                 s"Probe is started in the external JVM process with both stdout and stderr piped out into log file. " +
-                s"Command will block until the probe is started unless ${y("'--no-wait'")} parameter is used or timeout is expired."
+                s"Command will block until the probe is started unless ${y("'--noWait'")} parameter is used or timeout is expired."
             ),
             body = NCCli.cmdStartProbe,
             params = Seq(
                 Parameter(
                     id = "config",
-                    names = Seq("--config", "-c"),
+                    names = Seq("--cfg", "-c"),
                     value = Some("path"),
                     optional = true,
                     desc =
                         s"Configuration file path. Probe will automatically look for ${y("'nlpcraft.conf'")} " +
                         s"configuration file in the same directory as NLPCraft JAR file. If the configuration file has " +
                         s"different name or in different location use this parameter to provide an alternative path. " +
-                        s"Note that the server and the probe can use the same file for their configuration."
+                        s"Note that the server and the probe can use the same file for their configuration. " +
+                        s"Note also that you can use ${c("'~'")} at the beginning of the path to specify user home directory."
                 ),
                 Parameter(
                     id = "cp",
@@ -690,23 +693,24 @@ private [cmdline] object NCCliCommands {
                         s"Additional JVM classpath that will be appended to the default NLPCraft JVM classpath. " +
                         s"Although this configuration property is optional, when deploying your own models you must " +
                         s"provide this additional classpath for the models and their dependencies this probe will be hosting. " +
-                        s"NOTE: this is only optional if you are running example models shipped with NLPCraft."
+                        s"Note that this is only optional if you are running example models shipped with NLPCraft. " +
+                        s"Note also that you can use ${c("'~'")} at the beginning of the classpath component to specify user home directory."
                 ),
                 Parameter(
                     id = "models",
-                    names = Seq("--models", "-m"),
+                    names = Seq("--mdls", "-m"),
                     value = Some("<model list>"),
                     optional = true,
                     desc =
                         s"Comma separated list of fully qualified class names for models to deploy. This will override " +
                         s"${y("'nlpcraft.probe.models'")} configuration property from either default configuration file " +
-                        s"or the one provided by ${y("--config")} parameter. NOTE: if you provide the list of your " +
+                        s"or the one provided by ${y("--cfg")} parameter. Note that if you provide the list of your " +
                         s"own models here or in configuration file - you must also provide the additional classpath " +
                         s"for them via ${y("--cp")} parameter."
                 ),
                 Parameter(
                     id = "jvmopts",
-                    names = Seq("--jvm-opts", "-j"),
+                    names = Seq("--jvmOpts", "-j"),
                     value = Some("<jvm flags>"),
                     optional = true,
                     desc =
@@ -715,14 +719,14 @@ private [cmdline] object NCCliCommands {
                 ),
                 Parameter(
                     id = "noWait",
-                    names = Seq("--no-wait"),
+                    names = Seq("--noWait"),
                     optional = true,
                     desc =
                         s"Instructs command not to wait for the probe startup and return immediately."
                 ),
                 Parameter(
                     id = "timeoutMins",
-                    names = Seq("--timeout-mins", "-t"),
+                    names = Seq("--timeoutMins", "-t"),
                     optional = true,
                     value = Some("3"),
                     desc =
@@ -737,11 +741,11 @@ private [cmdline] object NCCliCommands {
                 Example(
                     usage = Seq(
                         s"$PROMPT $SCRIPT_NAME start-probe ",
-                        "  --config=/opt/nlpcraft.conf ",
-                        "  --models=my.package.Model ",
-                        "  --cp=/opt/target/classes ",
-                        "  --jmv-opts=\"-ea -Xms2048m\" ",
-                        "  --timeout-mins=5"
+                        "  --cfg=~/myapp/nlpcraft.conf ",
+                        "  --mdls=my.package.Model ",
+                        "  --cp=~/myapp/target/classes ",
+                        "  --jmvOpts=\"-ea -Xms2048m\" ",
+                        "  --timeoutMins=5"
                     ),
                     desc =
                         s"Starts local probe for ${y("'my.package.Model'")} model with alternative configuration " +
@@ -764,13 +768,14 @@ private [cmdline] object NCCliCommands {
             params = Seq(
                 Parameter(
                     id = "config",
-                    names = Seq("--config", "-c"),
+                    names = Seq("--cfg", "-c"),
                     value = Some("path"),
                     optional = true,
                     desc =
                         s"Configuration file path. By default, the embedded probe will automatically look for ${y("'nlpcraft.conf'")} " +
                         s"configuration file in the same directory as NLPCraft JAR file. If the configuration file has " +
-                        s"different name or in different location use this parameter to provide an alternative path."
+                        s"different name or in different location use this parameter to provide an alternative path. " +
+                        s"Note also that you can use ${c("'~'")} at the beginning of the path to specify user home directory."
                 ),
                 Parameter(
                     id = "cp",
@@ -781,11 +786,12 @@ private [cmdline] object NCCliCommands {
                         s"Additional JVM classpath that will be appended to the default NLPCraft JVM classpath. " +
                         s"Although this configuration property is optional, when testing your own models you must " +
                         s"provide this additional classpath for the models and their dependencies. " +
-                        s"NOTE: this is only optional if you are testing example models shipped with NLPCraft."
+                        s"Note that this is only optional if you are testing example models shipped with NLPCraft. " +
+                        s"Note also that you can use ${c("'~'")} at the beginning of the classpath component to specify user home directory."
                 ),
                 Parameter(
                     id = "models",
-                    names = Seq("--models", "-m"),
+                    names = Seq("--mdls", "-m"),
                     value = Some("<model list>"),
                     optional = true,
                     desc =
@@ -795,7 +801,7 @@ private [cmdline] object NCCliCommands {
                 ),
                 Parameter(
                     id = "jvmopts",
-                    names = Seq("--jvm-opts", "-j"),
+                    names = Seq("--jvmOpts", "-j"),
                     value = Some("<jvm flags>"),
                     optional = true,
                     desc =
@@ -807,9 +813,9 @@ private [cmdline] object NCCliCommands {
                 Example(
                     usage = Seq(
                         s"$PROMPT $SCRIPT_NAME test-model ",
-                        "  --models=my.package.Model ",
-                        "  --cp=/opt/target/classes ",
-                        "  --jmv-opts=\"-ea -Xms2048m\""
+                        "  --mdls=my.package.Model ",
+                        "  --cp=~/myapp/target/classes ",
+                        "  --jmvOpts=\"-ea -Xms2048m\""
                     ),
                     desc =
                         s"Runs model auto-validator for ${y("'my.package.Model'")} model."
@@ -868,7 +874,7 @@ private [cmdline] object NCCliCommands {
                     usage = Seq(s"$PROMPT $SCRIPT_NAME version -s no-logo"),
                     desc =
                         s"Displays just the version information without any additional logo output. " +
-                            s"This command makes sense only in command lime mode (NOT in REPL mode)."
+                        s"This command makes sense only in command lime mode (NOT in REPL mode)."
                 )
             )
         ),
@@ -899,7 +905,7 @@ private [cmdline] object NCCliCommands {
                 Parameter(
                     id = "number",
                     names = Seq("--number", "-n"),
-                    value = Some("num"),
+                    value = Some("1"),
                     optional = true,
                     desc =
                         "Number of pings to perform. Must be a number > 0. Default is 1."
@@ -993,14 +999,14 @@ private [cmdline] object NCCliCommands {
             params = Seq(
                 Parameter(
                     id = "semver",
-                    names = Seq("--sem-ver", "-s"),
+                    names = Seq("--semVer", "-s"),
                     value = None,
                     optional = true,
                     desc = s"Display only the semantic version value, e.g. ${VER.version}."
                 ),
                 Parameter(
                     id = "reldate",
-                    names = Seq("--rel-date", "-d"),
+                    names = Seq("--relDate", "-d"),
                     value = None,
                     optional = true,
                     desc = s"Display only the release date, e.g. ${VER.date}."
@@ -1022,7 +1028,9 @@ private [cmdline] object NCCliCommands {
                     names = Seq("--outputDir", "-d"),
                     value = Some("path"),
                     optional = true,
-                    desc = s"Output directory. Default value is the current working directory."
+                    desc =
+                        s"Output directory. Default value is the current working directory. " +
+                        s"Note that you can use ${c("'~'")} at the beginning of the path to specify user home directory."
                 ),
                 Parameter(
                     id = "baseName",
@@ -1052,14 +1060,14 @@ private [cmdline] object NCCliCommands {
                 ),
                 Parameter(
                     id = "packageName",
-                    names = Seq("--packageName", "-p"),
+                    names = Seq("--pckgName", "-p"),
                     value = Some("name"),
                     optional = true,
                     desc = s"JVM package name to use in generated source code. Default value is ${y("'org.apache.nlpcraft.demo'")}."
                 ),
                 Parameter(
                     id = "modelType",
-                    names = Seq("--modelType", "-m"),
+                    names = Seq("--mdlType", "-m"),
                     value = Some("type"),
                     optional = true,
                     desc = s"Type of generated model file. Supported value are ${y("'yaml'")} or ${y("'json'")}. Default value is ${y("'yaml'")}."
@@ -1067,9 +1075,8 @@ private [cmdline] object NCCliCommands {
                 Parameter(
                     id = "override",
                     names = Seq("--override", "-o"),
-                    value = Some("true|false"),
                     optional = true,
-                    desc = s"Whether or not to override existing output directory. Default value is ${y("'false'")}."
+                    desc = s"Overrides existing output directory, if any."
                 )
             ),
             examples = Seq(
@@ -1078,7 +1085,7 @@ private [cmdline] object NCCliCommands {
                     desc = s"Generates Scala SBT project."
                 ),
                 Example(
-                    usage = Seq("> gen-project -n=MyProject -l=kotlin -p=com.mycompany.nlp -o=true"),
+                    usage = Seq("> gen-project -n=MyProject -l=kotlin -p=com.mycompany.nlp -o"),
                     desc = s"Generates Kotlin Maven project."
                 )
             )
@@ -1099,29 +1106,29 @@ private [cmdline] object NCCliCommands {
                     desc =
                         s"File path for the model stub. File path can either be an absolute path, relative path or " +
                         s"just a file name in which case the current folder will be used. File must have one of the " +
-                        s"following extensions: ${y("'json'")}, ${y("'js'")}, ${y("'yaml'")}, or ${y("'yml'")}."
+                        s"following extensions: ${y("'json'")}, ${y("'js'")}, ${y("'yaml'")}, or ${y("'yml'")}. " +
+                        s"Note that you can use ${c("'~'")} at the beginning of the path to specify user home directory."
                 ),
                 Parameter(
                     id = "modelId",
-                    names = Seq("--modelId", "-n"),
+                    names = Seq("--mdlId", "-m"),
                     value = Some("id"),
                     desc = "Model ID."
                 ),
                 Parameter(
                     id = "override",
                     names = Seq("--override", "-o"),
-                    value = Some("true|false"),
                     optional = true,
-                    desc = s"Override output directory flag. Supported: ${y("'true'")}, ${y("'false'")}. Default value is ${y("'false'")}"
+                    desc = s"Overrides output file, if any."
                 )
             ),
             examples = Seq(
                 Example(
-                    usage = Seq("> gen-model -f=myModel.json -n=my.model.id"),
+                    usage = Seq("> gen-model --filePath=~/myapp/myModel.json --mdlId=my.model.id"),
                     desc = s"Generates JSON model file stub in the current folder."
                 ),
                 Example(
-                    usage = Seq("> gen-model -f=c:/tmp/myModel.yaml -n=my.model.id --override=true"),
+                    usage = Seq("> gen-model -f=c:/tmp/myModel.yaml -m=my.model.id -o"),
                     desc = s"Generates YAML model file stub in ${y("'c:/temp'")} folder overriding existing file, if any."
                 )
             )