     path
     (files/join (or (::dir object/*behavior-meta*) (files/lt-home)) path)))
 
+(defn local-module [plugin-name module-name]
+  (files/join plugins-dir plugin-name "node_modules" module-name))
+
+(cmd/command {:command :build
+              :desc "Editor: build file or project"
+              :exec (fn []
+                      (when-let [ed (pool/last-active)]
+                        (object/raise ed :build)))})
+
+;;*********************************************************
+;; Plugin reading
+;;*********************************************************
+
 (defn validate [plugin]
   (let [valid? (every? plugin [:name :author :behaviors :desc])]
     (if-not valid?
       (do
-        (console/error (str "Invalid plugin.json file: " (:dir plugin) "/plugin.json \nPlugins must include values for name, author, behaviors, and desc."))
+        (console/error (str "Invalid plugin.json file: " (:dir plugin) "/plugin.json \nPlugins
+                            must include values for name, version, author, behaviors, and desc."))
         nil)
       plugin)))
 



(def plugins-dir (files/lt-home "plugins"))

(defn EOF-read [s]
  (when (and s

                          (object/merge! this {::plugin-path (files/parent plugin-edn)})
                          (object/add-tags this [:plugin.file])))))

;;*********************************************************
;; App-level init
;;*********************************************************

;;This call to tag-behaviors is necessary as there are no behaviors loaded when the
;;app is first run.
(object/tag-behaviors :app [::init-plugins ::plugin-behavior-diffs ::plugin-keymap-diffs])