                @new-opts
                subcommand-args)) ; NOTE: ignores unknown args before the subcommand
       (cond (:help opts) (do (println banner) (System/exit 0))
-            (:action command) ((:action command) opts command-args)
+            (:action command) ((:action command) @new-opts command-args)
             :else (do (println banner) (System/exit 1))))))
-
-
-#_
-(command "vault [global opts] <command> [command args]"
-  "Command-line tool for the vault data store."
-
-  ["--blob-store" "Path to blob-store configuration."
-   :default "~/.config/vault/blob-store.edn"]
-  ["-v" "--verbose" "Show extra debugging messages."
-   :flag true :default false]
-  ["-h" "--help" "Show usage information."
-   :flag true :default false]
-
-  (init [opts]
-    (-> opts
-        (assoc :blob-store (slurp (:blob-store opts)))))
-
-  (command "blob [opts] <action> [args]"
-    "Blob storage command."
-
-    (command "list [opts]"
-      "Enumerate the stored blobs."
-      ; ... filtering/range options
-      (action blob-tool/list-blobs))
-
-    (command "info <blobref>"
-      "Show information about a stored blob."
-      (action blob-tool/blob-info))
-
-    (command "get <blobref>"
-      "Print the contents of a blob to stdout."
-      (action blob-tool/get-blob))
-
-    (command "put"
-      "Store a blob of data and print the resulting blobref."
-      (action blob-tool/put-blob))))
 
 
 
 ;; COMMAND LINE INTERFACE
 
+(def command-tree
+  (command "vault [global opts] <command> [command args]"
+    "Command-line tool for the vault data store."
+
+    ["--blob-store" "Path to blob-store configuration."
+     :default "~/.config/vault/blob-store.edn"]
+    ["-v" "--verbose" "Show extra debugging messages."
+     :flag true :default false]
+    ["-h" "--help" "Show usage information."
+     :flag true :default false]
+
+    #_ (init [opts]
+      (-> opts
+          (assoc :blob-store (slurp (:blob-store opts)))))
+
+    (command "blob [opts] <action> [args]"
+      "Blob storage command."
+
+      (command "list [opts]"
+        "Enumerate the stored blobs."
+        ; ... filtering/range options
+        (action vector #_ blob-tool/list-blobs))
+
+      (command "info <blobref>"
+        "Show information about a stored blob."
+        (action vector #_ blob-tool/blob-info))
+
+      (command "get <blobref>"
+        "Print the contents of a blob to stdout."
+        (action vector #_ blob-tool/get-blob))
+
+      (command "put"
+        "Store a blob of data read from stdin and print the resulting blobref."
+        (action vector #_ blob-tool/put-blob)))))
+
+
 (defn -main [& args]
-  (let [[opts args banner]
-        (cli
-          args
-          "Usage: vault [global opts] <system> <command> [command args]"
-          ["--blob-store" "Path to blob-store configuration."
-           :default "~/.config/vault/blob-store.edn"]
-          ["-v" "--verbose" "Show extra debugging messages."
-           :flag true :default false]
-          ["-h" "--help"    "Show usage information."
-           :flag true :default false])]
-    (when (:help opts)
-      (println banner)
-      (System/exit 0))
-    ;; TODO: command-line processing
-    (println "Opts: " opts)
-    (let [[system action & args] args]
-      (println "System: " system)
-      (println "Action: " action)
-      (println "Args: " args))))
+  (handle-command command-tree {} args))

 :action (fn [opts args] ...)}


(defn handle-command
  [command opts args]
  (let [subcommand-names (into #{} (cons "help" (keys (:commands command))))


;; $ vault object ...
;; $ vault group ...



;; COMMAND TREE STRUCTURE

; command nodes look like this:
#_
{:name "vault"
 :usage "vault [global opts] <command> [command args]"
 :desc "Command-line tool for the vault data store."
 :specs [["--blob-store" "Path to blob-store configuration." ...]]
 :init (fn [opts] ...)
