diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,31 @@
 # Revision history for ogma-cli
 
+## [1.15.0] - 2026-07-21
+
+* Version bump (1.15.0) (#508).
+* Fix typo in README (#428).
+* Update CI job to install Copilot 4.7.1 by default (#446).
+* Fix style of record definitions, constructions in multiple commands (#454).
+* Adjust `overview` command to accept multiple input files (#456).
+* Adjust `overview`, `standalone`, app commands to support projects (#460).
+* Expose `search` command (#464).
+* Fix syntax, grammatical errors in diagram tutorial (#466).
+* Fix links in documentation (#468).
+* Remove unnecessary vertical space (#470).
+* Update variable DBs in examples to indicate which inputs are active (#474).
+* Expose diagram mode argument to cFS backend (#476).
+* Add example explaining cFS app generation from state machine diagrams (#478).
+* Add example containing Doorstop requirements (#480).
+* Remove mentions of ICAROUS (#482).
+* Replace ROS2 with ROS 2 in help message (#484).
+* Adjust `report` command to accept multiple input files (#486).
+* Adjust `report` command to support projects (#488).
+* Remove unused import from `CLI.CommandStandalone` module (#490).
+* Apply multiple style fixes (#492).
+* Standardize option name in `report` command (#505).
+* Update CI job, examples for cFS 7.0 (#509).
+* Add example demonstrating how to generate monitor for Turtlesim demo (#507).
+
 ## [1.14.0] - 2026-05-21
 
 * Version bump (1.14.0) (#425).
diff --git a/ogma-cli.cabal b/ogma-cli.cabal
--- a/ogma-cli.cabal
+++ b/ogma-cli.cabal
@@ -19,7 +19,7 @@
 build-type:          Simple
 
 name:                ogma-cli
-version:             1.14.0
+version:             1.15.0
 homepage:            https://github.com/nasa/ogma
 bug-reports:         https://github.com/nasa/ogma/issues
 license:             Apache-2.0
@@ -78,6 +78,7 @@
                      >
                      >Available commands:
                      >  overview                 Generate an overview of the input specification(s)
+                     >  search                   List items that match search query
                      >  structs                  Generate Copilot structs from C structs
                      >  handlers                 Generate message handlers from C structs
                      >  cfs                      Generate a complete CFS/Copilot application
@@ -134,6 +135,7 @@
     CLI.CommandOverview
     CLI.CommandReport
     CLI.CommandROSApp
+    CLI.CommandSearch
     CLI.CommandStandalone
     CLI.CommandTop
     CLI.Result
@@ -145,7 +147,7 @@
     , microstache          >= 1.0      && < 1.1
     , text                 >= 1.2.3.1  && < 2.2
 
-    , ogma-core            >= 1.14.0 && < 1.15
+    , ogma-core            >= 1.15.0 && < 1.16
 
   hs-source-dirs:
     src
diff --git a/src/CLI/CommandCFSApp.hs b/src/CLI/CommandCFSApp.hs
--- a/src/CLI/CommandCFSApp.hs
+++ b/src/CLI/CommandCFSApp.hs
@@ -30,11 +30,16 @@
   where
 
 -- External imports
+import Control.Applicative ( (<|>) )
+import Data.Functor        ( (<&>) )
+import Data.Maybe          ( fromMaybe )
 import Options.Applicative ( Parser, help, long, many, metavar, optional,
                              short, showDefault, strOption, value )
 
--- External imports: command results
-import Command.Result ( Result )
+-- External imports: handling of input projects and command results
+import Command.Result ( Result (..) )
+import Data.Location  ( Location ( LocationFile ) )
+import Data.Project   ( Project (..), readProject )
 
 -- External imports: actions or commands supported
 import           Command.CFSApp ( ErrorCode )
@@ -44,17 +49,19 @@
 
 -- | Options needed to generate the cFS application.
 data CommandOpts = CommandOpts
-  { cFSAppConditionExpr  :: Maybe String
-  , cFSAppInputFiles   :: [String]
-  , cFSAppTarget       :: String
-  , cFSAppTemplateDir  :: Maybe String
-  , cFSAppVarNames     :: Maybe String
-  , cFSAppVarDB        :: Maybe String
-  , cFSAppHandlers     :: Maybe String
-  , cFSAppFormat       :: String
-  , cFSAppPropFormat   :: String
-  , cFSAppPropVia      :: Maybe String
-  , cFSAppTemplateVars :: Maybe String
+  { cFSAppProject       :: Maybe String
+  , cFSAppConditionExpr :: Maybe String
+  , cFSAppInputFiles    :: [String]
+  , cFSAppTarget        :: String
+  , cFSAppTemplateDir   :: Maybe String
+  , cFSAppVarNames      :: Maybe String
+  , cFSAppVarDB         :: Maybe String
+  , cFSAppHandlers      :: Maybe String
+  , cFSAppFormat        :: String
+  , cFSAppPropFormat    :: String
+  , cFSAppPropVia       :: Maybe String
+  , cFSAppDiagramMode   :: String
+  , cFSAppTemplateVars  :: Maybe String
   }
 
 -- | Create <https://cfs.gsfc.nasa.gov/ NASA core Flight System> (cFS)
@@ -63,22 +70,78 @@
 --
 -- This is just an uncurried version of "Command.CFSApp".
 command :: CommandOpts -> IO (Result ErrorCode)
-command c = Command.CFSApp.command options
-  where
-    options = Command.CFSApp.CommandOptions
-                { Command.CFSApp.commandConditionExpr = cFSAppConditionExpr c
-                , Command.CFSApp.commandInputFiles  = cFSAppInputFiles c
-                , Command.CFSApp.commandTargetDir   = cFSAppTarget c
-                , Command.CFSApp.commandTemplateDir = cFSAppTemplateDir c
-                , Command.CFSApp.commandVariables   = cFSAppVarNames c
-                , Command.CFSApp.commandVariableDB  = cFSAppVarDB c
-                , Command.CFSApp.commandHandlers    = cFSAppHandlers c
-                , Command.CFSApp.commandFormat      = cFSAppFormat c
-                , Command.CFSApp.commandPropFormat  = cFSAppPropFormat c
-                , Command.CFSApp.commandPropVia     = cFSAppPropVia c
-                , Command.CFSApp.commandExtraVars   = cFSAppTemplateVars c
-                }
+command c
+  | Just p <- cFSAppProject c
+  = do optE <- commandProjectOptions p c
+       case optE of
+         Left msg  -> return $ Error cannotReadProject msg (LocationFile p)
+         Right opt -> Command.CFSApp.command opt
 
+  | otherwise
+  = Command.CFSApp.command $
+      Command.CFSApp.CommandOptions
+        { Command.CFSApp.commandConditionExpr = cFSAppConditionExpr c
+        , Command.CFSApp.commandInputFiles    = cFSAppInputFiles c
+        , Command.CFSApp.commandTargetDir     = cFSAppTarget c
+        , Command.CFSApp.commandTemplateDir   = cFSAppTemplateDir c
+        , Command.CFSApp.commandVariables     = cFSAppVarNames c
+        , Command.CFSApp.commandVariableDB    = cFSAppVarDB c
+        , Command.CFSApp.commandHandlers      = cFSAppHandlers c
+        , Command.CFSApp.commandFormat        = cFSAppFormat c
+        , Command.CFSApp.commandPropFormat    = cFSAppPropFormat c
+        , Command.CFSApp.commandPropVia       = cFSAppPropVia c
+        , Command.CFSApp.commandDiagramMode   = cFSAppDiagramMode c
+        , Command.CFSApp.commandExtraVars     = cFSAppTemplateVars c
+        }
+
+-- | Produce default command options based on project settings.
+commandProjectOptions :: FilePath
+                      -> CommandOpts
+                      -> IO (Either String Command.CFSApp.CommandOptions)
+commandProjectOptions projectFile c = do
+  projectE <- readProject projectFile
+  return $ projectE <&> \project ->
+    Command.CFSApp.CommandOptions
+      { Command.CFSApp.commandConditionExpr = cFSAppConditionExpr c
+
+      , Command.CFSApp.commandInputFiles = concat
+          [ map (\(f, _, _) -> f) $ projectInputFiles project
+          , cFSAppInputFiles c
+          ]
+
+      , Command.CFSApp.commandTargetDir =
+          fromMaybe (cFSAppTarget c) (projectTargetDir project)
+
+      , Command.CFSApp.commandTemplateDir =
+          projectTemplateDir project <|> cFSAppTemplateDir c
+
+      , Command.CFSApp.commandVariables =
+          projectVariableFiles project <|> cFSAppVarNames c
+
+      , Command.CFSApp.commandVariableDB =
+          projectVariableDBFile project <|> cFSAppVarDB c
+
+      , Command.CFSApp.commandHandlers =
+          projectHandlerFile project <|> cFSAppHandlers c
+
+      , Command.CFSApp.commandFormat = case projectInputFiles project of
+          []            -> cFSAppFormat c
+          ((_, f, _):_) -> f
+
+      , Command.CFSApp.commandPropFormat = case projectInputFiles project of
+          []            -> cFSAppPropFormat c
+          ((_, _, f):_) -> f
+
+      , Command.CFSApp.commandPropVia =
+          projectCommandPropVia project <|> cFSAppPropVia c
+
+      , Command.CFSApp.commandDiagramMode = cFSAppDiagramMode c
+
+      , Command.CFSApp.commandExtraVars =
+          projectExtraJSONFile project <|> cFSAppTemplateVars c
+
+      }
+
 -- * CLI
 
 -- | cFS command description
@@ -91,6 +154,13 @@
 commandOptsParser = CommandOpts
   <$> optional
         ( strOption
+            (  long "project"
+            <> metavar "FILENAME"
+            <> help strCFSAppProjectArgDesc
+            )
+        )
+  <*> optional
+        ( strOption
             (  long "condition-expr"
             <> metavar "EXPRESSION"
             <> help strCFSAppConditionExprArgDesc
@@ -161,6 +231,13 @@
             <> help strCFSAppPropViaDesc
             )
         )
+  <*> strOption
+        (  long "mode"
+        <> metavar "MODE"
+        <> help strCFSAppDiagramModeDesc
+        <> showDefault
+        <> value "calculate"
+        )
   <*> optional
         ( strOption
             (  long "template-vars"
@@ -169,6 +246,10 @@
             )
         )
 
+-- | Argument project to cFS app generation command.
+strCFSAppProjectArgDesc :: String
+strCFSAppProjectArgDesc = "Project file"
+
 -- | Argument target directory to cFS app generation command
 strCFSAppDirArgDesc :: String
 strCFSAppDirArgDesc = "Target directory"
@@ -188,16 +269,15 @@
 strCFSAppFileNameArgDesc =
   "File containing input specification"
 
-
 -- | Argument variable list to cFS app generation command
 strCFSAppVarListArgDesc :: String
 strCFSAppVarListArgDesc =
-  "File containing list of cFS/ICAROUS variables to make accessible"
+  "File containing list of cFS variables to make accessible"
 
 -- | Argument variable database to cFS app generation command
 strCFSAppVarDBArgDesc :: String
 strCFSAppVarDBArgDesc =
-  "File containing a DB of known cFS/ICAROUS variables"
+  "File containing a DB of known cFS variables"
 
 -- | Argument handler list to cFS app generation command
 strCFSAppHandlerListArgDesc :: String
@@ -217,7 +297,16 @@
 strCFSAppPropViaDesc =
   "Command to pre-process individual properties"
 
+-- | Mode name flag description.
+strCFSAppDiagramModeDesc :: String
+strCFSAppDiagramModeDesc =
+  "Mode of operation for diagrams (check, calculate, safeguard)"
+
 -- | Argument template variables to cFS app generation command
 strCFSAppTemplateVarsArgDesc :: String
 strCFSAppTemplateVarsArgDesc =
   "JSON file containing additional variables to expand in template"
+
+-- | Error code for when a project cannot be read.
+cannotReadProject :: ErrorCode
+cannotReadProject = 1
diff --git a/src/CLI/CommandFPrimeApp.hs b/src/CLI/CommandFPrimeApp.hs
--- a/src/CLI/CommandFPrimeApp.hs
+++ b/src/CLI/CommandFPrimeApp.hs
@@ -30,11 +30,16 @@
   where
 
 -- External imports
+import Control.Applicative ( (<|>) )
+import Data.Functor        ( (<&>) )
+import Data.Maybe          ( fromMaybe )
 import Options.Applicative ( Parser, help, long, many, metavar, optional,
                              short, showDefault, strOption, value )
 
--- External imports: command results
-import Command.Result ( Result )
+-- External imports: handling of input projects and command results
+import Command.Result ( Result (..) )
+import Data.Location  ( Location (LocationFile) )
+import Data.Project   ( Project (..), readProject )
 
 -- External imports: actions or commands supported
 import           Command.FPrimeApp (ErrorCode)
@@ -44,17 +49,18 @@
 
 -- | Options needed to generate the FPrime component.
 data CommandOpts = CommandOpts
-  { fprimeAppConditionExpr  :: Maybe String
-  , fprimeAppInputFiles   :: [String]
-  , fprimeAppTarget       :: String
-  , fprimeAppTemplateDir  :: Maybe String
-  , fprimeAppVariables    :: Maybe String
-  , fprimeAppVarDB        :: Maybe String
-  , fprimeAppHandlers     :: Maybe String
-  , fprimeAppFormat       :: String
-  , fprimeAppPropFormat   :: String
-  , fprimeAppPropVia      :: Maybe String
-  , fprimeAppTemplateVars :: Maybe String
+  { fprimeAppProject       :: Maybe String
+  , fprimeAppConditionExpr :: Maybe String
+  , fprimeAppInputFiles    :: [String]
+  , fprimeAppTarget        :: String
+  , fprimeAppTemplateDir   :: Maybe String
+  , fprimeAppVariables     :: Maybe String
+  , fprimeAppVarDB         :: Maybe String
+  , fprimeAppHandlers      :: Maybe String
+  , fprimeAppFormat        :: String
+  , fprimeAppPropFormat    :: String
+  , fprimeAppPropVia       :: Maybe String
+  , fprimeAppTemplateVars  :: Maybe String
   }
 
 -- | Create <https://github.com/nasa/fprime FPrime> component that subscribe
@@ -63,23 +69,77 @@
 --
 -- This is just a wrapper around "Command.fprimeApp".
 command :: CommandOpts -> IO (Result ErrorCode)
-command c = Command.FPrimeApp.command options
+command c
+    | Just p <- fprimeAppProject c
+    = do optE <- commandProjectOptions p c
+         case optE of
+           Left msg  -> return $ Error cannotReadProject msg (LocationFile p)
+           Right opt -> Command.FPrimeApp.command opt
+
+    | otherwise
+    = Command.FPrimeApp.command options
   where
     options =
       Command.FPrimeApp.CommandOptions
         { Command.FPrimeApp.commandConditionExpr = fprimeAppConditionExpr c
-        , Command.FPrimeApp.commandInputFiles  = fprimeAppInputFiles c
-        , Command.FPrimeApp.commandTargetDir   = fprimeAppTarget c
-        , Command.FPrimeApp.commandTemplateDir = fprimeAppTemplateDir c
-        , Command.FPrimeApp.commandVariables   = fprimeAppVariables c
-        , Command.FPrimeApp.commandVariableDB  = fprimeAppVarDB c
-        , Command.FPrimeApp.commandHandlers    = fprimeAppHandlers c
-        , Command.FPrimeApp.commandFormat      = fprimeAppFormat c
-        , Command.FPrimeApp.commandPropFormat  = fprimeAppPropFormat c
-        , Command.FPrimeApp.commandPropVia     = fprimeAppPropVia c
-        , Command.FPrimeApp.commandExtraVars   = fprimeAppTemplateVars c
+        , Command.FPrimeApp.commandInputFiles    = fprimeAppInputFiles c
+        , Command.FPrimeApp.commandTargetDir     = fprimeAppTarget c
+        , Command.FPrimeApp.commandTemplateDir   = fprimeAppTemplateDir c
+        , Command.FPrimeApp.commandVariables     = fprimeAppVariables c
+        , Command.FPrimeApp.commandVariableDB    = fprimeAppVarDB c
+        , Command.FPrimeApp.commandHandlers      = fprimeAppHandlers c
+        , Command.FPrimeApp.commandFormat        = fprimeAppFormat c
+        , Command.FPrimeApp.commandPropFormat    = fprimeAppPropFormat c
+        , Command.FPrimeApp.commandPropVia       = fprimeAppPropVia c
+        , Command.FPrimeApp.commandExtraVars     = fprimeAppTemplateVars c
         }
 
+-- | Produce default command options based on project settings.
+commandProjectOptions :: FilePath
+                      -> CommandOpts
+                      -> IO (Either String Command.FPrimeApp.CommandOptions)
+commandProjectOptions projectFile c = do
+  projectE <- readProject projectFile
+  return $ projectE <&> \project ->
+    Command.FPrimeApp.CommandOptions
+      { Command.FPrimeApp.commandConditionExpr = fprimeAppConditionExpr c
+
+      , Command.FPrimeApp.commandInputFiles = concat
+          [ map (\(f, _, _) -> f) $ projectInputFiles project
+          , fprimeAppInputFiles c
+          ]
+
+      , Command.FPrimeApp.commandTargetDir =
+          fromMaybe (fprimeAppTarget c) (projectTargetDir project)
+
+      , Command.FPrimeApp.commandTemplateDir =
+          maybe (fprimeAppTemplateDir c) Just (projectTemplateDir project)
+
+      , Command.FPrimeApp.commandVariables =
+          projectVariableFiles project <|> fprimeAppVariables c
+
+      , Command.FPrimeApp.commandVariableDB =
+          projectVariableDBFile project <|> fprimeAppVarDB c
+
+      , Command.FPrimeApp.commandHandlers =
+          projectHandlerFile project <|> fprimeAppHandlers c
+
+      , Command.FPrimeApp.commandFormat = case projectInputFiles project of
+          []            -> fprimeAppFormat c
+          ((_, f, _):_) -> f
+
+      , Command.FPrimeApp.commandPropFormat = case projectInputFiles project of
+          []            -> fprimeAppPropFormat c
+          ((_, _, f):_) -> f
+
+      , Command.FPrimeApp.commandPropVia =
+          projectCommandPropVia project <|> fprimeAppPropVia c
+
+      , Command.FPrimeApp.commandExtraVars =
+          projectExtraJSONFile project <|> fprimeAppTemplateVars c
+
+      }
+
 -- * CLI
 
 -- | FPrime command description
@@ -92,6 +152,13 @@
 commandOptsParser = CommandOpts
   <$> optional
         ( strOption
+            (  long "project"
+            <> metavar "FILENAME"
+            <> help strFPrimeAppProjectArgDesc
+            )
+        )
+  <*> optional
+        ( strOption
             (  long "condition-expr"
             <> metavar "EXPRESSION"
             <> help strFPrimeAppConditionExprArgDesc
@@ -170,6 +237,10 @@
             )
         )
 
+-- | Argument project to FPrime app generation command.
+strFPrimeAppProjectArgDesc :: String
+strFPrimeAppProjectArgDesc = "Project file"
+
 -- | Argument target directory to FPrime component generation command
 strFPrimeAppDirArgDesc :: String
 strFPrimeAppDirArgDesc = "Target directory"
@@ -181,7 +252,8 @@
 
 -- | Argument expression to FPrime app generation command.
 strFPrimeAppConditionExprArgDesc :: String
-strFPrimeAppConditionExprArgDesc = "Expression used as guard or trigger condition"
+strFPrimeAppConditionExprArgDesc =
+  "Expression used as guard or trigger condition"
 
 -- | Argument input file to FPrime component generation command
 strFPrimeAppFileNameArgDesc :: String
@@ -220,3 +292,7 @@
 strFPrimeAppTemplateVarsArgDesc :: String
 strFPrimeAppTemplateVarsArgDesc =
   "JSON file containing additional variables to expand in template"
+
+-- | Error code for when a project cannot be read.
+cannotReadProject :: ErrorCode
+cannotReadProject = 1
diff --git a/src/CLI/CommandOverview.hs b/src/CLI/CommandOverview.hs
--- a/src/CLI/CommandOverview.hs
+++ b/src/CLI/CommandOverview.hs
@@ -32,14 +32,19 @@
 
 -- External imports
 import           Data.Aeson          (toJSON)
+import           Data.Functor        ((<&>))
+import           Data.List           (dropWhileEnd)
 import qualified Data.Text.Lazy      as T
 import qualified Data.Text.Lazy.IO   as T
-import           Options.Applicative (Parser, help, long, metavar, optional,
-                                      short, showDefault, strOption, value)
-import           Text.Microstache
+import           Options.Applicative (Parser, help, long, many, metavar,
+                                      optional, short, showDefault, strOption,
+                                      value)
+import           Text.Microstache    (compileMustacheText, renderMustache)
 
--- External imports: command results
+-- External imports: handling of input projects and command results
 import Command.Result ( Result(..) )
+import Data.Location  ( Location(..) )
+import Data.Project   ( Project (..), readProject )
 
 -- External imports: actions or commands supported
 import           Command.Overview (ErrorCode)
@@ -49,61 +54,129 @@
 
 -- | Options to generate an overview from the input specification(s).
 data CommandOpts = CommandOpts
-  { overviewInputFile   :: FilePath
-  , overviewFormat      :: String
-  , overviewPropFormat  :: String
-  , overviewPropVia     :: Maybe String
+  { overviewProject    :: Maybe String
+  , overviewInputFiles :: [OverviewFile]
   }
 
+-- | Options associated to a specific input file.
+data OverviewFile = OverviewFile
+  { overviewFilePath       :: FilePath
+  , overviewFileFormat     :: String
+  , overviewFilePropFormat :: String
+  , overviewFilePropVia    :: Maybe String
+  }
+
 -- | Print an overview of the input specification(s).
 command :: CommandOpts -> IO (Result ErrorCode)
-command c = do
-    (mOutput, result) <-
-      Command.Overview.command (overviewInputFile c) internalCommandOpts
+command c
+    | Just p <- overviewProject c
+    = do optE <- commandProjectOptions p c
+         case optE of
+           Left msg  -> return $ Error cannotReadProject msg (LocationFile p)
+           Right opt -> do
+             (mOutput, result) <- Command.Overview.command opt
+             case mOutput of
+               Just output ->
+                 case outputString of
+                   Right template -> T.putStr $ trimEnd
+                                   $ renderMustache template (toJSON output)
+                   _              -> putStrLn "Error"
+               _ -> putStrLn "Error"
+             return result
 
-    case mOutput of
-      Just output ->
-        case outputString output of
-          Right template -> T.putStr $ renderMustache template (toJSON output)
-          _              -> putStrLn "Error"
-      _ -> putStrLn "Error"
-    return result
+     | otherwise
+     = do (mOutput, result) <-
+            Command.Overview.command internalCommandOpts
 
+          case mOutput of
+            Just output ->
+              case outputString of
+                Right template ->
+                  T.putStr $ trimEnd $ renderMustache template (toJSON output)
+                _              -> putStrLn "Error"
+            _ -> putStrLn "Error"
+          return result
+
   where
+
+    trimEnd :: T.Text -> T.Text
+    trimEnd = T.unlines . dropWhileEnd T.null . T.lines
+
     internalCommandOpts :: Command.Overview.CommandOptions
-    internalCommandOpts = Command.Overview.CommandOptions
-      { Command.Overview.commandFormat      = overviewFormat c
-      , Command.Overview.commandPropFormat  = overviewPropFormat c
-      , Command.Overview.commandPropVia     = overviewPropVia c
+    internalCommandOpts = Command.Overview.CommandOptions $
+      map fileInfo (overviewInputFiles c)
+
+    fileInfo f = Command.Overview.OverviewFile
+      { Command.Overview.overviewFilePath       = overviewFilePath   f
+      , Command.Overview.overviewFileFormat     = overviewFileFormat f
+      , Command.Overview.overviewFilePropFormat = overviewFilePropFormat f
+      , Command.Overview.overviewFilePropVia    = overviewFilePropVia f
       }
 
-    outputString (Command.Overview.CommandSummaryRequirement {}) =
+    outputString =
       compileMustacheText "output" $ T.unlines
-        [ "The requirements file has:"
+        [ "{{#commandSummaryRequirements}}"
+        , "The requirements file {{commandRequirementsFile}} has:"
         , " - {{commandExternalVariables}} external variables."
         , " - {{commandInternalVariables}} internal variables."
         , " - {{commandRequirements}} requirements."
-        , "   - {{commandRequirementsTrue}} requirements are constantly or always true."
-        , "   - {{commandRequirementsFalse}} requirements are constantly or always false."
+        , "   - {{commandRequirementsTrue}} requirements are constantly or "
+          <> "always true."
+        , "   - {{commandRequirementsFalse}} requirements are constantly or "
+          <> "always false."
         , "{{#commandRequirementsConsistent}}"
         , "   - No inconsistencies detected in the requirements."
         , "{{/commandRequirementsConsistent}}"
         , "{{^commandRequirementsConsistent}}"
         , "   - The requirements are not mutually consistent."
         , "{{/commandRequirementsConsistent}}"
-        ]
-    outputString (Command.Overview.CommandSummaryDiagram {}) =
-      compileMustacheText "output" $ T.unlines
-        [ "The diagram file:"
-        , " - Has {{commandNumStates}} states."
-        , "{{#commandDeterministic}}"
+        , ""
+        , "{{/commandSummaryRequirements}}"
+        , "{{#commandSummaryDiagrams}}"
+        , "The diagram file {{commandDiagramFile}}:"
+        , " - Has {{commandDiagramNumStates}} states."
+        , "{{#commandDiagramDeterministic}}"
         , " - Is deterministic."
-        , "{{/commandDeterministic}}"
-        , "{{^commandDeterministic}}"
+        , "{{/commandDiagramDeterministic}}"
+        , "{{^commandDiagramDeterministic}}"
         , " - Is not deterministic."
-        , "{{/commandDeterministic}}"
+        , "{{/commandDiagramDeterministic}}"
+        , ""
+        , "{{/commandSummaryDiagrams}}"
         ]
 
+-- | Produce command options based on project settings and user-provided
+-- command options.
+commandProjectOptions :: FilePath
+                      -> CommandOpts
+                      -> IO (Either String Command.Overview.CommandOptions)
+commandProjectOptions projectFile c = do
+    projectE <- readProject projectFile
+    return $ projectE <&> \project ->
+      Command.Overview.CommandOptions
+        { Command.Overview.commandInputFiles = concat
+            [ map (convertProjectFile project) $ projectInputFiles project
+            , map convertInputFile $ overviewInputFiles c
+            ]
+        }
+
+  where
+
+    convertProjectFile project (fp, format, propFormat) =
+      Command.Overview.OverviewFile
+        { Command.Overview.overviewFilePath       = fp
+        , Command.Overview.overviewFileFormat     = format
+        , Command.Overview.overviewFilePropFormat = propFormat
+        , Command.Overview.overviewFilePropVia    =
+            projectCommandPropVia project
+        }
+    convertInputFile f = Command.Overview.OverviewFile
+      { Command.Overview.overviewFilePath       = overviewFilePath   f
+      , Command.Overview.overviewFileFormat     = overviewFileFormat f
+      , Command.Overview.overviewFilePropFormat = overviewFilePropFormat f
+      , Command.Overview.overviewFilePropVia    = overviewFilePropVia f
+      }
+
 -- * CLI
 
 -- | Command description for CLI help.
@@ -114,6 +187,19 @@
 -- of the input specifications.
 commandOptsParser :: Parser CommandOpts
 commandOptsParser = CommandOpts
+  <$> optional
+        ( strOption
+            (  long "project"
+            <> metavar "FILENAME"
+            <> help strOverviewProjectArgDesc
+            )
+        )
+  <*> many overviewFileOptsParser
+
+-- | Subparser for information on one input file to be used with the @overview@
+-- command.
+overviewFileOptsParser :: Parser OverviewFile
+overviewFileOptsParser = OverviewFile
   <$> strOption
         (  long "input-file"
         <> metavar "FILENAME"
@@ -143,6 +229,10 @@
             )
         )
 
+-- | Project flag description.
+strOverviewProjectArgDesc :: String
+strOverviewProjectArgDesc = "Project file"
+
 -- | Input file flag description.
 strOverviewInputFileDesc :: String
 strOverviewInputFileDesc = "File with properties or requirements"
@@ -159,3 +249,7 @@
 strOverviewPropViaDesc :: String
 strOverviewPropViaDesc =
   "Command to pre-process individual properties"
+
+-- | Error code for when a project cannot be read.
+cannotReadProject :: ErrorCode
+cannotReadProject = 1
diff --git a/src/CLI/CommandROSApp.hs b/src/CLI/CommandROSApp.hs
--- a/src/CLI/CommandROSApp.hs
+++ b/src/CLI/CommandROSApp.hs
@@ -30,11 +30,16 @@
   where
 
 -- External imports
+import Control.Applicative ( (<|>) )
+import Data.Functor        ( (<&>) )
+import Data.Maybe          ( fromMaybe )
 import Options.Applicative ( Parser, help, long, metavar, many, optional, short,
                              showDefault, strOption, value )
 
--- External imports: command results
-import Command.Result ( Result )
+-- External imports: handling of input projects and command results
+import Command.Result ( Result (..) )
+import Data.Location  ( Location ( LocationFile ) )
+import Data.Project   ( Project (..), readProject )
 
 -- External imports: actions or commands supported
 import           Command.ROSApp (ErrorCode)
@@ -44,19 +49,20 @@
 
 -- | Options needed to generate the ROS application.
 data CommandOpts = CommandOpts
-  { rosAppConditionExpr  :: Maybe String
-  , rosAppInputFiles   :: [String]
-  , rosAppTarget       :: String
-  , rosAppTemplateDir  :: Maybe String
-  , rosAppVarNames     :: Maybe String
-  , rosAppVarDB        :: Maybe String
-  , rosAppHandlers     :: Maybe String
-  , rosAppFormat       :: String
-  , rosAppPropFormat   :: String
-  , rosAppPropVia      :: Maybe String
-  , rosAppTemplateVars :: Maybe String
-  , rosAppTestingApps  :: [String]
-  , rosAppTestingVars  :: [String]
+  { rosAppProject       :: Maybe String
+  , rosAppConditionExpr :: Maybe String
+  , rosAppInputFiles    :: [String]
+  , rosAppTarget        :: String
+  , rosAppTemplateDir   :: Maybe String
+  , rosAppVarNames      :: Maybe String
+  , rosAppVarDB         :: Maybe String
+  , rosAppHandlers      :: Maybe String
+  , rosAppFormat        :: String
+  , rosAppPropFormat    :: String
+  , rosAppPropVia       :: Maybe String
+  , rosAppTemplateVars  :: Maybe String
+  , rosAppTestingApps   :: [String]
+  , rosAppTestingVars   :: [String]
   }
 
 -- | Create <https://www.ros.org/ Robot Operating System> (ROS) applications
@@ -65,22 +71,30 @@
 --
 -- This is just a wrapper around "Command.ROSApp".
 command :: CommandOpts -> IO (Result ErrorCode)
-command c = Command.ROSApp.command options
+command c
+    | Just p <- rosAppProject c
+    = do optE <- commandProjectOptions p c
+         case optE of
+           Left msg  -> return $ Error cannotReadProject msg (LocationFile p)
+           Right opt -> Command.ROSApp.command opt
+
+    | otherwise
+    = Command.ROSApp.command options
   where
     options = Command.ROSApp.CommandOptions
                 { Command.ROSApp.commandConditionExpr = rosAppConditionExpr c
-                , Command.ROSApp.commandInputFiles  = rosAppInputFiles c
-                , Command.ROSApp.commandTargetDir   = rosAppTarget c
-                , Command.ROSApp.commandTemplateDir = rosAppTemplateDir c
-                , Command.ROSApp.commandVariables   = rosAppVarNames c
-                , Command.ROSApp.commandVariableDB  = rosAppVarDB c
-                , Command.ROSApp.commandHandlers    = rosAppHandlers c
-                , Command.ROSApp.commandFormat      = rosAppFormat c
-                , Command.ROSApp.commandPropFormat  = rosAppPropFormat c
-                , Command.ROSApp.commandPropVia     = rosAppPropVia c
-                , Command.ROSApp.commandExtraVars   = rosAppTemplateVars c
-                , Command.ROSApp.commandTestingApps = appNames
-                , Command.ROSApp.commandTestingVars = rosAppTestingVars c
+                , Command.ROSApp.commandInputFiles    = rosAppInputFiles c
+                , Command.ROSApp.commandTargetDir     = rosAppTarget c
+                , Command.ROSApp.commandTemplateDir   = rosAppTemplateDir c
+                , Command.ROSApp.commandVariables     = rosAppVarNames c
+                , Command.ROSApp.commandVariableDB    = rosAppVarDB c
+                , Command.ROSApp.commandHandlers      = rosAppHandlers c
+                , Command.ROSApp.commandFormat        = rosAppFormat c
+                , Command.ROSApp.commandPropFormat    = rosAppPropFormat c
+                , Command.ROSApp.commandPropVia       = rosAppPropVia c
+                , Command.ROSApp.commandExtraVars     = rosAppTemplateVars c
+                , Command.ROSApp.commandTestingApps   = appNames
+                , Command.ROSApp.commandTestingVars   = rosAppTestingVars c
                 }
 
     -- Turn the qualified app names into tuples of package and node name.
@@ -90,6 +104,66 @@
       where
         (package, nodeT) = break (== ':') name
 
+-- | Produce default command options based on project settings.
+commandProjectOptions :: FilePath
+                      -> CommandOpts
+                      -> IO (Either String Command.ROSApp.CommandOptions)
+commandProjectOptions projectFile c = do
+    projectE <- readProject projectFile
+    return $ projectE <&> \project ->
+      Command.ROSApp.CommandOptions
+        { Command.ROSApp.commandConditionExpr = rosAppConditionExpr c
+
+        , Command.ROSApp.commandInputFiles = concat
+            [ map (\(f, _, _) -> f) $ projectInputFiles project
+            , rosAppInputFiles c
+            ]
+
+        , Command.ROSApp.commandTargetDir =
+            fromMaybe (rosAppTarget c) (projectTargetDir project)
+
+        , Command.ROSApp.commandTemplateDir =
+            projectTemplateDir project <|> rosAppTemplateDir c
+
+        , Command.ROSApp.commandVariables =
+            projectVariableFiles project <|> rosAppVarNames c
+
+        , Command.ROSApp.commandVariableDB =
+            projectVariableDBFile project <|> rosAppVarDB c
+
+        , Command.ROSApp.commandHandlers =
+            projectHandlerFile project <|> rosAppHandlers c
+
+        , Command.ROSApp.commandFormat = case projectInputFiles project of
+            []            -> rosAppFormat c
+            ((_, f, _):_) -> f
+
+        , Command.ROSApp.commandPropFormat =
+            case projectInputFiles project of
+              []            -> rosAppPropFormat c
+              ((_, _, f):_) -> f
+
+        , Command.ROSApp.commandPropVia =
+            projectCommandPropVia project <|> rosAppPropVia c
+
+        , Command.ROSApp.commandExtraVars =
+            projectExtraJSONFile project <|> rosAppTemplateVars c
+
+        , Command.ROSApp.commandTestingApps = appNames
+
+        , Command.ROSApp.commandTestingVars = rosAppTestingVars c
+
+        }
+
+  where
+
+    -- Turn the qualified app names into tuples of package and node name.
+    appNames = map splitAppName $ rosAppTestingApps c
+
+    splitAppName name = Command.ROSApp.Node package (drop 1 nodeT)
+      where
+        (package, nodeT) = break (== ':') name
+
 -- * CLI
 
 -- | ROS command description
@@ -102,6 +176,13 @@
 commandOptsParser = CommandOpts
   <$> optional
         ( strOption
+            (  long "project"
+            <> metavar "FILENAME"
+            <> help strROSAppProjectArgDesc
+            )
+        )
+  <*> optional
+        ( strOption
             (  long "condition-expr"
             <> metavar "EXPRESSION"
             <> help strROSAppConditionExprArgDesc
@@ -193,6 +274,10 @@
               )
            )
 
+-- | Argument project to ROS app generation command.
+strROSAppProjectArgDesc :: String
+strROSAppProjectArgDesc = "Project file"
+
 -- | Argument target directory to ROS app generation command
 strROSAppDirArgDesc :: String
 strROSAppDirArgDesc = "Target directory"
@@ -247,9 +332,13 @@
 -- | Argument packages to tested list to ROS app generation command
 strROSAppROSNodesTestingListArgDesc :: String
 strROSAppROSNodesTestingListArgDesc =
-  "Turn on ROS2 package node during testing"
+  "Turn on ROS 2 package node during testing"
 
 -- | Argument variables to be tested list to ROS app generation command
 strROSAppVarsTestingListArgDesc :: String
 strROSAppVarsTestingListArgDesc =
   "Limit random input generation to these variables"
+
+-- | Error code for when a project cannot be read.
+cannotReadProject :: ErrorCode
+cannotReadProject = 1
diff --git a/src/CLI/CommandReport.hs b/src/CLI/CommandReport.hs
--- a/src/CLI/CommandReport.hs
+++ b/src/CLI/CommandReport.hs
@@ -43,11 +43,16 @@
   where
 
 -- External imports
-import Options.Applicative (Parser, help, long, metavar, optional, short,
+import Control.Applicative ((<|>))
+import Data.Functor        ((<&>))
+import Data.Maybe          (fromMaybe)
+import Options.Applicative (Parser, help, long, many, metavar, optional, short,
                             showDefault, strOption, value)
 
--- External imports: command results
+-- External imports: handling of input projects and command results
 import Command.Result (Result (..))
+import Data.Location  (Location (LocationFile))
+import Data.Project   (Project (..), readProject)
 
 -- External imports: actions or commands supported
 import           Command.Report (ErrorCode)
@@ -57,33 +62,76 @@
 
 -- | Options to generate Copilot from specification.
 data CommandOpts = CommandOpts
-  { commandTargetDir   :: FilePath           -- ^ Target directory where the
+  { commandProject     :: Maybe String       -- ^ Project file.
+  , commandTargetDir   :: FilePath           -- ^ Target directory where the
                                              -- reoprt should be created.
   , commandTemplateDir :: Maybe FilePath     -- ^ Directory where the template
                                              -- is to be found.
-  , commandFileName    :: FilePath
-  , commandFormat      :: String
-  , commandPropFormat  :: String
-  , commandPropVia     :: Maybe String
+  , commandInputFiles  :: [ReportFile]
   }
 
+-- | Options associated to a specific input file.
+data ReportFile = ReportFile
+  { reportFilePath       :: FilePath
+  , reportFileFormat     :: String
+  , reportFilePropFormat :: String
+  , reportFilePropVia    :: Maybe String
+  }
+
 -- | Generate a report of the input specification(s).
 command :: CommandOpts -- ^ Customization options
         -> IO (Result ErrorCode)
-command options = do
-    Command.Report.command internalCommandOpts
+command options
+    | Just p <- commandProject options
+    = do optE <- commandProjectOptions p options
+         case optE of
+           Left msg  -> return $ Error cannotReadProject msg (LocationFile p)
+           Right opt -> Command.Report.command opt
 
+    | otherwise
+    = Command.Report.command internalCommandOpts
+
   where
     internalCommandOpts :: Command.Report.CommandOptions
     internalCommandOpts = Command.Report.CommandOptions
       { Command.Report.commandTargetDir   = commandTargetDir options
       , Command.Report.commandTemplateDir = commandTemplateDir options
-      , Command.Report.commandInputFile   = commandFileName options
-      , Command.Report.commandFormat      = commandFormat options
-      , Command.Report.commandPropFormat  = commandPropFormat options
-      , Command.Report.commandPropVia     = commandPropVia options
+      , Command.Report.commandInputFiles  =
+          map argumentToReportFile $ commandInputFiles options
       }
 
+-- | Produce default command options based on project settings.
+commandProjectOptions :: FilePath
+                      -> CommandOpts
+                      -> IO (Either String Command.Report.CommandOptions)
+commandProjectOptions projectFile c = do
+  projectE <- readProject projectFile
+  return $ projectE <&> \project ->
+
+    let projectToReportFile (fp, c1, c2) =
+          Command.Report.ReportFile fp c1 c2 (projectCommandPropVia project)
+
+    in Command.Report.CommandOptions
+         { Command.Report.commandTargetDir   =
+             fromMaybe (commandTargetDir c) (projectTargetDir project)
+         , Command.Report.commandTemplateDir =
+             projectTemplateDir project <|> commandTemplateDir c
+         , Command.Report.commandInputFiles  = concat
+             [ map projectToReportFile  $ projectInputFiles project
+             , map argumentToReportFile $ commandInputFiles c
+             ]
+         }
+
+-- | Convert an input argument file into an internal
+-- 'Command.Report.ReportFile'.
+argumentToReportFile :: ReportFile -> Command.Report.ReportFile
+argumentToReportFile f = Command.Report.ReportFile
+  { Command.Report.reportFilePath       = reportFilePath   f
+  , Command.Report.reportFileFormat     = reportFileFormat f
+  , Command.Report.reportFilePropFormat = reportFilePropFormat f
+  , Command.Report.reportFilePropVia    = reportFilePropVia f
+  }
+
 -- * CLI
 
 -- | Command description for CLI help.
@@ -94,7 +142,14 @@
 -- specification from an input specification file.
 commandOptsParser :: Parser CommandOpts
 commandOptsParser = CommandOpts
-  <$> strOption
+  <$> optional
+        ( strOption
+            (  long "project"
+            <> metavar "FILENAME"
+            <> help strReportProjectArgDesc
+            )
+        )
+  <*> strOption
         (  long "target-dir"
         <> metavar "DIR"
         <> showDefault
@@ -108,10 +163,16 @@
             <> help strReportTemplateDirArgDesc
             )
         )
-  <*> strOption
-        (  long "file-name"
+  <*> many reportFileOptsParser
+
+-- | Subparser for information on one input file to be used with the @report@
+-- command.
+reportFileOptsParser :: Parser ReportFile
+reportFileOptsParser = ReportFile
+  <$> strOption
+        (  long "input-file"
         <> metavar "FILENAME"
-        <> help strReportFilenameDesc
+        <> help strReportInputFileDesc
         )
   <*> strOption
         (  long "input-format"
@@ -137,6 +198,10 @@
             )
         )
 
+-- | Project flag description.
+strReportProjectArgDesc :: String
+strReportProjectArgDesc = "Project file"
+
 -- | Target dir flag description.
 strReportTargetDirDesc :: String
 strReportTargetDirDesc = "Target directory"
@@ -145,9 +210,9 @@
 strReportTemplateDirArgDesc :: String
 strReportTemplateDirArgDesc = "Directory holding report template"
 
--- | Filename flag description.
-strReportFilenameDesc :: String
-strReportFilenameDesc = "File with properties, requirements or a diagram"
+-- | Input file flag description.
+strReportInputFileDesc :: String
+strReportInputFileDesc = "File with properties, requirements or a diagram"
 
 -- | Format flag description.
 strReportFormatDesc :: String
@@ -160,3 +225,7 @@
 -- | External command to pre-process individual properties.
 strReportPropViaDesc :: String
 strReportPropViaDesc = "Command to pre-process individual properties"
+
+-- | Error code for when a project cannot be read.
+cannotReadProject :: ErrorCode
+cannotReadProject = 1
diff --git a/src/CLI/CommandSearch.hs b/src/CLI/CommandSearch.hs
new file mode 100644
--- /dev/null
+++ b/src/CLI/CommandSearch.hs
@@ -0,0 +1,243 @@
+{-# LANGUAGE OverloadedStrings #-}
+-- Copyright 2020 United States Government as represented by the Administrator
+-- of the National Aeronautics and Space Administration. All Rights Reserved.
+--
+-- Disclaimers
+--
+-- Licensed under the Apache License, Version 2.0 (the "License"); you may
+-- not use this file except in compliance with the License. You may obtain a
+-- copy of the License at
+--
+--      https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+-- License for the specific language governing permissions and limitations
+-- under the License.
+--
+-- | CLI interface to the Search subcommand.
+module CLI.CommandSearch
+    (
+      -- * Direct command access
+      command
+    , CommandOpts
+    , ErrorCode
+
+      -- * CLI
+    , commandDesc
+    , commandOptsParser
+    )
+  where
+
+-- External imports
+import           Data.Aeson          (toJSON)
+import           Data.Functor        ((<&>))
+import qualified Data.Text.Lazy      as T
+import qualified Data.Text.Lazy.IO   as T
+import           Options.Applicative (Parser, help, long, many, metavar,
+                                      optional, short, showDefault, strOption,
+                                      value)
+import           Text.Microstache    (compileMustacheText, renderMustache)
+
+-- External imports: handling of input projects and command results
+import Command.Result (Result (..))
+import Data.Location  (Location (..))
+import Data.Project   (Project (..), readProject)
+
+-- External imports: actions or commands supported
+import           Command.Search (ErrorCode)
+import qualified Command.Search
+
+-- * Command
+
+-- | Options to generate an search from the input specification(s).
+data CommandOpts = CommandOpts
+  { searchProject    :: Maybe String
+  , searchQuery      :: String
+  , searchInputFiles :: [SearchFile]
+  }
+
+-- | Options associated to a specific input file.
+data SearchFile = SearchFile
+  { searchFilePath       :: FilePath
+  , searchFileFormat     :: String
+  , searchFilePropFormat :: String
+  , searchFilePropVia    :: Maybe String
+  }
+
+-- | Print an search of the input specification(s).
+command :: CommandOpts -> IO (Result ErrorCode)
+command c
+    | Just p <- searchProject c
+    = do optE <- commandProjectOptions p c
+         case optE of
+           Left msg  -> return $ Error cannotReadProject msg (LocationFile p)
+           Right opt -> do
+             (mOutput, result) <- Command.Search.command opt
+             case mOutput of
+               Just output ->
+                 case outputString of
+                   Right template ->
+                     T.putStr $ renderMustache template (toJSON output)
+                   _              -> putStrLn "Error"
+               _           -> putStrLn "Error"
+             return result
+
+     | otherwise
+     = do (mOutput, result) <-
+            Command.Search.command internalCommandOpts
+
+          case mOutput of
+            Just output ->
+              case outputString of
+                Right template ->
+                  T.putStr $ renderMustache template (toJSON output)
+                _              -> putStrLn "Error"
+            _           -> putStrLn "Error"
+          return result
+
+  where
+
+    internalCommandOpts :: Command.Search.CommandOptions
+    internalCommandOpts = Command.Search.CommandOptions
+      { Command.Search.commandInputFiles  = map fileInfo (searchInputFiles c)
+      , Command.Search.commandSearchQuery = searchQuery c
+      }
+
+    fileInfo f = Command.Search.SearchFile
+      { Command.Search.searchFilePath       = searchFilePath   f
+      , Command.Search.searchFileFormat     = searchFileFormat f
+      , Command.Search.searchFilePropFormat = searchFilePropFormat f
+      , Command.Search.searchFilePropVia    = searchFilePropVia f
+      }
+
+    outputString =
+      compileMustacheText "output" $ T.unlines
+        [ "{{#searchResultRequirements}}"
+        , "{{requirementInfoLocation}}: requirement "
+          <> "\"{{requirementInfoName}}\" matches"
+        , "{{/searchResultRequirements}}"
+        , "{{#searchResultDiagrams}}"
+        , "{{diagramInfoLocation}}: diagram file matches"
+        , "{{/searchResultDiagrams}}"
+        ]
+
+-- | Produce command options based on project settings and user-provided
+-- command options.
+commandProjectOptions :: FilePath
+                      -> CommandOpts
+                      -> IO (Either String Command.Search.CommandOptions)
+commandProjectOptions projectFile c = do
+    projectE <- readProject projectFile
+    return $ projectE <&> \project ->
+      Command.Search.CommandOptions
+        { Command.Search.commandInputFiles = concat
+            [ map (convertProjectFile project) $ projectInputFiles project
+            , map convertInputFile $ searchInputFiles c
+            ]
+        , Command.Search.commandSearchQuery = searchQuery c
+        }
+
+  where
+
+    convertProjectFile project (fp, format, propFormat) =
+      Command.Search.SearchFile
+        { Command.Search.searchFilePath       = fp
+        , Command.Search.searchFileFormat     = format
+        , Command.Search.searchFilePropFormat = propFormat
+        , Command.Search.searchFilePropVia    =
+            projectCommandPropVia project
+        }
+    convertInputFile f = Command.Search.SearchFile
+      { Command.Search.searchFilePath       = searchFilePath   f
+      , Command.Search.searchFileFormat     = searchFileFormat f
+      , Command.Search.searchFilePropFormat = searchFilePropFormat f
+      , Command.Search.searchFilePropVia    = searchFilePropVia f
+      }
+
+-- * CLI
+
+-- | Command description for CLI help.
+commandDesc :: String
+commandDesc = "List items that match search query"
+
+-- | Subparser for the @search@ command, used to generate an search
+-- of the input specifications.
+commandOptsParser :: Parser CommandOpts
+commandOptsParser = CommandOpts
+  <$> optional
+        ( strOption
+            (  long "project"
+            <> metavar "FILENAME"
+            <> help strSearchProjectArgDesc
+            )
+        )
+  <*> strOption
+        (  long "query"
+        <> metavar "STRING"
+        <> help strSearchQueryArgDesc
+        )
+  <*> many searchFileOptsParser
+
+-- | Subparser for information on one input file to be used with the @search@
+-- command.
+searchFileOptsParser :: Parser SearchFile
+searchFileOptsParser = SearchFile
+  <$> strOption
+        (  long "input-file"
+        <> metavar "FILENAME"
+        <> help strSearchInputFileDesc
+        )
+  <*> strOption
+        (  long "input-format"
+        <> short 'f'
+        <> metavar "FORMAT_NAME"
+        <> help strSearchFormatDesc
+        <> showDefault
+        <> value "fcs"
+        )
+  <*> strOption
+        (  long "prop-format"
+        <> short 'p'
+        <> metavar "FORMAT_NAME"
+        <> help strSearchPropFormatDesc
+        <> showDefault
+        <> value "smv"
+        )
+  <*> optional
+        ( strOption
+            (  long "parse-prop-via"
+            <> metavar "COMMAND"
+            <> help strSearchPropViaDesc
+            )
+        )
+
+-- | Project flag description.
+strSearchProjectArgDesc :: String
+strSearchProjectArgDesc = "Project file"
+
+-- | Query flag description.
+strSearchQueryArgDesc :: String
+strSearchQueryArgDesc = "Search string"
+
+-- | Input file flag description.
+strSearchInputFileDesc :: String
+strSearchInputFileDesc = "File with properties or requirements"
+
+-- | Format flag description.
+strSearchFormatDesc :: String
+strSearchFormatDesc = "Format of the input file"
+
+-- | Property format flag description.
+strSearchPropFormatDesc :: String
+strSearchPropFormatDesc = "Format of temporal or boolean properties"
+
+-- | External command to pre-process individual properties.
+strSearchPropViaDesc :: String
+strSearchPropViaDesc =
+  "Command to pre-process individual properties"
+
+-- | Error code for when a project cannot be read.
+cannotReadProject :: ErrorCode
+cannotReadProject = 1
diff --git a/src/CLI/CommandStandalone.hs b/src/CLI/CommandStandalone.hs
--- a/src/CLI/CommandStandalone.hs
+++ b/src/CLI/CommandStandalone.hs
@@ -30,12 +30,16 @@
   where
 
 -- External imports
+import Control.Applicative ((<|>))
+import Data.Functor        ((<&>))
+import Data.Maybe          (fromMaybe)
 import Options.Applicative (Parser, help, long, many, metavar, optional, short,
-                            showDefault, strOption, switch, value)
+                            showDefault, strOption, value)
 
--- External imports: command results
+-- External imports: handling of input projects and command results
 import Command.Result ( Result(..) )
 import Data.Location  ( Location(..) )
+import Data.Project   ( Project (..), readProject )
 
 -- External imports: actions or commands supported
 import           Command.Standalone (ErrorCode)
@@ -45,40 +49,96 @@
 
 -- | Options to generate Copilot from specification.
 data CommandOpts = CommandOpts
-  { standaloneTargetDir    :: FilePath
-  , standaloneTemplateDir  :: Maybe FilePath
-  , standaloneConditionExpr  :: Maybe String
-  , standaloneInputFiles   :: [FilePath]
-  , standaloneFormat       :: String
-  , standalonePropFormat   :: String
-  , standaloneTypes        :: [String]
-  , standaloneTarget       :: String
-  , standalonePropVia      :: Maybe String
-  , standaloneTemplateVars :: Maybe String
+  { standaloneProject       :: Maybe String
+  , standaloneTargetDir     :: FilePath
+  , standaloneTemplateDir   :: Maybe FilePath
+  , standaloneConditionExpr :: Maybe String
+  , standaloneInputFiles    :: [FilePath]
+  , standaloneFormat        :: String
+  , standalonePropFormat    :: String
+  , standaloneTypes         :: [String]
+  , standaloneTarget        :: String
+  , standalonePropVia       :: Maybe String
+  , standaloneTemplateVars  :: Maybe String
   }
 
 -- | Transform an input specification into a Copilot specification.
 command :: CommandOpts -> IO (Result ErrorCode)
-command c =
-    Command.Standalone.command internalCommandOpts
+command c
+    | Just p <- standaloneProject c
+    = do optE <- commandProjectOptions p c
+         case optE of
+           Left msg  -> return $ Error cannotReadProject msg (LocationFile p)
+           Right opt -> Command.Standalone.command opt
+
+    | otherwise
+    = Command.Standalone.command internalCommandOpts
   where
     internalCommandOpts :: Command.Standalone.CommandOptions
     internalCommandOpts = Command.Standalone.CommandOptions
       { Command.Standalone.commandConditionExpr = standaloneConditionExpr c
-      , Command.Standalone.commandInputFiles  = standaloneInputFiles c
-      , Command.Standalone.commandTargetDir   = standaloneTargetDir c
-      , Command.Standalone.commandTemplateDir = standaloneTemplateDir c
-      , Command.Standalone.commandFormat      = standaloneFormat c
-      , Command.Standalone.commandPropFormat  = standalonePropFormat c
-      , Command.Standalone.commandTypeMapping = types
-      , Command.Standalone.commandFilename    = standaloneTarget c
-      , Command.Standalone.commandPropVia     = standalonePropVia c
-      , Command.Standalone.commandExtraVars   = standaloneTemplateVars c
+      , Command.Standalone.commandInputFiles    = standaloneInputFiles c
+      , Command.Standalone.commandTargetDir     = standaloneTargetDir c
+      , Command.Standalone.commandTemplateDir   = standaloneTemplateDir c
+      , Command.Standalone.commandFormat        = standaloneFormat c
+      , Command.Standalone.commandPropFormat    = standalonePropFormat c
+      , Command.Standalone.commandTypeMapping   = types
+      , Command.Standalone.commandFilename      = standaloneTarget c
+      , Command.Standalone.commandPropVia       = standalonePropVia c
+      , Command.Standalone.commandExtraVars     = standaloneTemplateVars c
       }
 
     types :: [(String, String)]
-    types = map splitTypeMapping (standaloneTypes c)
+    types = typeMapping (standaloneTypes c)
 
+-- | Produce command options based on project settings and user-provided
+-- command options.
+commandProjectOptions :: FilePath
+                      -> CommandOpts
+                      -> IO (Either String Command.Standalone.CommandOptions)
+commandProjectOptions projectFile c = do
+  projectE <- readProject projectFile
+  return $ projectE <&> \project ->
+    Command.Standalone.CommandOptions
+      { Command.Standalone.commandConditionExpr = standaloneConditionExpr c
+
+      , Command.Standalone.commandInputFiles = concat
+          [ map (\(f, _, _) -> f) $ projectInputFiles project
+          , standaloneInputFiles c
+          ]
+
+      , Command.Standalone.commandTargetDir =
+          fromMaybe (standaloneTargetDir c) (projectTargetDir project)
+
+      , Command.Standalone.commandTemplateDir =
+          projectTemplateDir project <|> standaloneTemplateDir c
+
+      , Command.Standalone.commandFormat =
+          case projectInputFiles project of
+            []            -> standaloneFormat c
+            ((_, f, _):_) -> f
+
+      , Command.Standalone.commandPropFormat =
+          case projectInputFiles project of
+            []            -> standalonePropFormat c
+            ((_, _, f):_) -> f
+
+      , Command.Standalone.commandPropVia =
+          projectCommandPropVia project <|> standalonePropVia c
+
+      , Command.Standalone.commandExtraVars =
+          projectExtraJSONFile project <|> standaloneTemplateVars c
+
+      , Command.Standalone.commandFilename = standaloneTarget c
+
+      , Command.Standalone.commandTypeMapping = typeMapping (standaloneTypes c)
+
+      }
+
+-- | Parse a list of type associations, where two types are separated by ':'.
+typeMapping :: [String] -> [(String, String)]
+typeMapping = map splitTypeMapping
+  where
     splitTypeMapping :: String -> (String, String)
     splitTypeMapping s = (h, safeTail t)
       where
@@ -96,7 +156,14 @@
 -- specification from an input specification file.
 commandOptsParser :: Parser CommandOpts
 commandOptsParser = CommandOpts
-  <$> strOption
+  <$> optional
+        ( strOption
+            (  long "project"
+            <> metavar "FILENAME"
+            <> help strStandaloneProjectArgDesc
+            )
+        )
+  <*> strOption
         (  long "target-dir"
         <> metavar "DIR"
         <> showDefault
@@ -169,6 +236,10 @@
             )
         )
 
+-- | Project flag description.
+strStandaloneProjectArgDesc :: String
+strStandaloneProjectArgDesc = "Project file"
+
 -- | Target dir flag description.
 strStandaloneTargetDirDesc :: String
 strStandaloneTargetDirDesc = "Target directory"
@@ -212,3 +283,7 @@
 strStandaloneTemplateVarsArgDesc :: String
 strStandaloneTemplateVarsArgDesc =
   "JSON file containing additional variables to expand in template"
+
+-- | Error code for when a project cannot be read.
+cannotReadProject :: ErrorCode
+cannotReadProject = 1
diff --git a/src/CLI/CommandTop.hs b/src/CLI/CommandTop.hs
--- a/src/CLI/CommandTop.hs
+++ b/src/CLI/CommandTop.hs
@@ -81,6 +81,7 @@
 import qualified CLI.CommandOverview
 import qualified CLI.CommandReport
 import qualified CLI.CommandROSApp
+import qualified CLI.CommandSearch
 import qualified CLI.CommandStandalone
 
 -- * Command
@@ -91,15 +92,16 @@
 -- @CommandOpts@ to capture their respective arguments. These types are
 -- different for each subcommand.
 data CommandOpts =
-    CommandOptsCFSApp                    CLI.CommandCFSApp.CommandOpts
-  | CommandOptsCStructs2Copilot          CLI.CommandCStructs2Copilot.CommandOpts
-  | CommandOptsCStructs2MsgHandlers      CLI.CommandCStructs2MsgHandlers.CommandOpts
-  | CommandOptsDiagram                   CLI.CommandDiagram.CommandOpts
-  | CommandOptsFPrimeApp                 CLI.CommandFPrimeApp.CommandOpts
-  | CommandOptsOverview                  CLI.CommandOverview.CommandOpts
-  | CommandOptsROSApp                    CLI.CommandROSApp.CommandOpts
-  | CommandOptsStandalone                CLI.CommandStandalone.CommandOpts
-  | CommandOptsReport                    CLI.CommandReport.CommandOpts
+    CommandOptsCFSApp               CLI.CommandCFSApp.CommandOpts
+  | CommandOptsCStructs2Copilot     CLI.CommandCStructs2Copilot.CommandOpts
+  | CommandOptsCStructs2MsgHandlers CLI.CommandCStructs2MsgHandlers.CommandOpts
+  | CommandOptsDiagram              CLI.CommandDiagram.CommandOpts
+  | CommandOptsFPrimeApp            CLI.CommandFPrimeApp.CommandOpts
+  | CommandOptsOverview             CLI.CommandOverview.CommandOpts
+  | CommandOptsROSApp               CLI.CommandROSApp.CommandOpts
+  | CommandOptsSearch               CLI.CommandSearch.CommandOpts
+  | CommandOptsStandalone           CLI.CommandStandalone.CommandOpts
+  | CommandOptsReport               CLI.CommandReport.CommandOpts
 
 -- * CLI
 
@@ -112,6 +114,7 @@
 commandOptsParser :: Parser CommandOpts
 commandOptsParser = subparser
   (  subcommandOverview
+  <> subcommandSearch
   <> subcommandCStructs
   <> subcommandMsgHandlers
   <> subcommandCFSApp
@@ -131,6 +134,15 @@
     (CommandOptsOverview <$> CLI.CommandOverview.commandOptsParser)
     CLI.CommandOverview.commandDesc
 
+-- | Modifier for the search subcommand, linking the subcommand options and
+-- description to the command @search@ at top level.
+subcommandSearch :: Mod CommandFields CommandOpts
+subcommandSearch =
+  subcommand
+    "search"
+    (CommandOptsSearch <$> CLI.CommandSearch.commandOptsParser)
+    CLI.CommandSearch.commandDesc
+
 -- | Modifier for the CStruct to Copilot Struct generation subcommand, linking
 -- the subcommand options and description to the command @structs@ at top
 -- level.
@@ -240,6 +252,8 @@
   id <$> CLI.CommandOverview.command c
 command (CommandOptsROSApp c) =
   id <$> CLI.CommandROSApp.command c
+command (CommandOptsSearch c) =
+  id <$> CLI.CommandSearch.command c
 command (CommandOptsStandalone c) =
   id <$> CLI.CommandStandalone.command c
 command (CommandOptsDiagram c) =
diff --git a/src/CLI/Result.hs b/src/CLI/Result.hs
--- a/src/CLI/Result.hs
+++ b/src/CLI/Result.hs
@@ -41,4 +41,5 @@
     showLocation LocationNothing        = "<no location info>: "
     showLocation (LocationFile f)       = f ++ ": "
     showLocation (LocationFileLine f l) = f ++ ":" ++ show l ++ ": "
-    showLocation (LocationFileLC f l c) = f ++ ":" ++ show l ++ ":" ++ show c ++ ": "
+    showLocation (LocationFileLC f l c) =
+      f ++ ":" ++ show l ++ ":" ++ show c ++ ": "
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -15,14 +15,14 @@
 -- License for the specific language governing permissions and limitations
 -- under the License.
 --
--- | Ogma: Tool to interoperate between <https://cfs.gsfc.nasa.gov/ Copilot>
--- and other languages.
+-- | Ogma: Tool to interoperate between
+-- <https://github.com/Copilot-Language/copilot Copilot> and other languages.
 --
 -- Ogma is a tool to facilitate integration of safe runtime monitors into other
 -- systems. It takes information from a system created in a language (e.g.,
 -- Lustre) and produces specifications for the runtime verification
--- framework <https://cfs.gsfc.nasa.gov/ Copilot>. Currently, features
--- supported are:
+-- framework <https://github.com/Copilot-Language/copilot Copilot>. Currently,
+-- features supported are:
 --
 -- * Translation properties defined in structured natural language into
 -- corresponding expressions in Copilot.
