                                                      query-keys)))
                           (map util/form->defn))
          all-forms   (cond-> all-forms
-                       cache-query (conj {:form-name 'cache-query
-                                          :form-body '()}))
+                       cache-query (conj {:form-name 'cache-query})
+                       data-spec   (conj {:form-name 'data-spec}))
          forms-map   (zipmap (map (comp keyword :form-name) all-forms)
                              (map (fn [form]
                                     (symbol (str (ns-name *ns*))


;;;; Command registry

(defonce ^:private command-registry (atom {}))

(defn register-command!
  [cmd-name]
  (let [cmd-sym        (util/unqualify cmd-name)
        definition-sym (util/prefix-form-name 'definition cmd-sym)
        definition     (resolve definition-sym)]
    (swap! command-registry assoc name definition)))

(defn resolve-command
  [cmd-name]
  (get @command-registry cmd-name))

;;;; The defcommand macro


         query-form  (when cache-query
                       `((~'def ~(util/prefix-form-name 'cache-query
                                                        name-sym)
                          '~cache-query)))
         spec-form   (when data-spec
                       `((~'def ~(util/prefix-form-name 'data-spec
                                                        name-sym)
                          ~data-spec)))
         definition  `(~'def ~(util/prefix-form-name 'definition
                                                     name-sym)
                       ~forms-map)]
     `(do
        ~@form-fns
        ~@query-form
        ~@spec-form
        ~definition))))

(defmacro defcommand
  [name & forms]
  (register-command! name &env)
  (defcommand* name forms &env))
