           true        (update-in [::start-figwheel-options :mode] #(if-not % :repl %)))]
     (default-compile cljs.repl.figwheel/repl-env cfg)))
 
-;; TODO still searching for an achitecture here
-;; we need a better overall plan for config data
-;; we need to be aiming towards concrete config for the actions to be taken
-;; :repl-env-options :repl-options and compiler :options
-;; :watcher options
-;; :background builds need their own options
-
-
-(def server (atom nil))
-
-(def ^:dynamic *config*)
+;; ----------------------------------------------------------------------------
+;; REPL api
+;; ----------------------------------------------------------------------------
+
+(defn clean-build [{:keys [output-to output-dir]}]
+  (when (and output-to output-dir)
+    (doseq [file (cons (io/file output-to)
+                       (reverse (file-seq (io/file output-dir))))]
+      (when (.exists file) (.delete file)))))
+
+(defn select-autobuild-watches [ids]
+  (->> ids
+       (map #(vector ::autobuild %))
+       (select-keys (:watches @fww/*watcher*))
+       vals))
+
+(defn currently-watched-ids []
+  (set (map second (filter
+               #(and (coll? %) (= (first %) ::autobuild))
+               (keys (:watches @fww/*watcher*))))))
+
+(defn warn-on-bad-id [ids]
+  (when-let [bad-ids (not-empty (remove (currently-watched-ids) ids))]
+    (doseq [bad-id bad-ids]
+      (println "No autobuild currently has id:" bad-id))))
+
+;; TODO should this default to cleaning all builds??
+;; I think yes
+(defn clean* [ids]
+  (let [ids (->> ids (map name) distinct)]
+    (warn-on-bad-id ids)
+    (doseq [watch' (select-autobuild-watches ids)]
+      #_(prn watch')
+      (when-let [options (-> watch' ::watch-info :options)]
+        (println "Cleaning build id:" (-> watch' ::watch-info :id))
+        (clean-build options)))))
+
+(defmacro clean [& ids]
+  (clean* (map name ids))
+  nil)
+
+(defn status* []
+  (println "------- Figwheel Main Status -------")
+  (if-let [ids (not-empty (currently-watched-ids))]
+    (println "Currently building:" (string/join ", " ids))
+    (println "No builds are currently being built.")))
+
+(defmacro status []
+  (status*) nil)
+
+(defn stop-builds* [ids]
+  (let [ids (->> ids (map name) distinct)]
+    (warn-on-bad-id ids)
+    (doseq [k (map #(vector ::autobuild %) ids)]
+      (when (-> fww/*watcher* deref :watches (get k))
+        (println "Stopped building id:" (last k))
+        (fww/remove-watch! k)))))
+
+;; TODO should this default to stopping all builds??
+;; I think yes
+(defmacro stop-builds [& ids]
+  (stop-builds* ids)
+  nil)
+
+(defn main-build? [id]
+  (and *config* (= (name id) (-> *config* ::build :id))))
+
+(defn hydrate-all-background-builds [cfg ids]
+  (reduce background-build-opt (dissoc cfg ::background-builds) ids))
+
+(defn start-builds* [ids]
+  (let [ids (->> ids (map name) distinct)
+        already-building (not-empty (filter (currently-watched-ids) ids))
+        ids (filter (complement (currently-watched-ids)) ids)]
+    (when (not-empty already-building)
+      (doseq [i already-building]
+        (println "Already building id: " i)))
+    (let [main-build-id     (first (filter main-build? ids))
+          bg-builds (remove main-build? ids)]
+      #_(prn main-build-id bg-builds)
+      (when main-build-id
+        (let [{:keys [options repl-env-options ::config]} *config*
+              {:keys [watch-dirs]} config]
+          (println "Starting build id:" main-build-id)
+          ;; TODO these fns should provide feedback internally
+          (bapi/build (apply bapi/inputs watch-dirs) options cljs.env/*compiler*)
+          (watch-build main-build-id
+                       watch-dirs options
+                       cljs.env/*compiler*
+                       (select-keys config [:reload-clj-files]))
+          (when (first (filter #{'figwheel.core} (:preloads options)))
+            (binding [cljs.repl/*repl-env* (figwheel.repl/repl-env*
+                                            (select-keys repl-env-options
+                                                         [:connection-filter]))]
+              (figwheel.core/start*)))))
+      (when (not-empty bg-builds)
+        (let [cfg (hydrate-all-background-builds
+                   {::start-figwheel-options (::config *config*)}
+                   bg-builds)]
+          (start-background-builds cfg))))))
+
+;; TODO should this default to stopping all builds??
+;; I think yes
+(defmacro start-builds [& ids]
+  (start-builds* ids)
+  nil)
+
+;; TODO reset, build-once
 
 ;; we should add a compile directory option
 

(defn watch-build [id inputs opts cenv & [reload-config]]
  (when-let [inputs (if (coll? inputs) inputs [inputs])]
    (fww/add-watch!
     id
     (merge
      {::watch-info (merge
                     (:extra-info reload-config)

    (if-let [paths (and (not= mode :build-once) (not-empty watch-dirs))]
      (do
        (bapi/build (apply bapi/inputs paths) options cenv)
        (watch-build (:id build "dev")
                     paths options cenv (select-keys config [:reload-clj-files])))
      (cond
        source
