diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c)2012, Sean Seefried
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Mark Wotton nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,134 @@
+# Commands
+
+## task start
+
+### Usage
+
+~~~
+task start <description> <key/value...>
+~~~
+
+
+
+### Flags:
+
+~~~
+-t, --time <time>              start at time
+-k, --key-value=<key/value>    Add key/value pair
+~~~
+
+Each key/value pair is of the form <key>:<value> where <key> and <value> are both JSON strings.
+
+## task finish
+
+Finish the current task, if there is one.
+
+### Usage
+
+~~~
+task finish
+~~~
+
+### Flags
+
+~~~
+-t, --time <time>      finish at time as long as it is after start time and not in future.
+~~~
+
+## task modify
+
+Modifies a single entry if it wouldn't overlap with another one or finish in the future.
+
+### Usage
+
+~~~
+task modify <flags>
+~~~
+
+### Flags
+
+~~~
+--id <id>              Modify the task with id <id>
+-s, --start <start>    Modify start time to <start>
+-f, --finish <finish>  Modify finish time to <finish>
+~~~
+
+## task delete
+
+### Usage
+
+~~~
+task delete <flags>
+~~~
+
+### Flags
+
+~~~
+-- id <id>    Delete the task with id <id>
+~~~
+
+## task query
+
+Allows you to query the database
+
+### Usage
+
+~~~
+task query <flags...>
+~~~
+
+### Flags
+
+~~~
+-f, --format        Format
+                      %s       start time
+                      %f       finish time
+                      %c       category
+                      %d       description
+                      %k<key>  key/value pair for key <key>
+                      %K       all key value pairs, comma seperated
+                        
+--gt <time>         Show all entries greater than <time>. Combines with other flags.
+--ge <time>         Like --gt but "greater than or equal to"
+--lt <time>         Like --gt but "less than"
+--le <time>         Like --gt but "less than or equal to"
+~~~
+
+## task export
+
+### Usage
+
+~~~
+task export <path>
+~~~
+
+### Flags
+
+~~~
+--csv    Export as CSV. Incompatible with --json
+--json   Export as JSON. Incompatible with --csv
+~~~
+
+# Appendix
+
+## Valid keys
+
+Keys can be any valid identifier other than `id`, `start`, `finish`, `category`, `description`. 
+See *Identifiers*.
+
+## Identifiers
+
+Acceptable characters for ids are JSON strings. JSON strings are
+
+1. any Unicode character except `"` or the `\` control character.
+2. a `\` followed by any of:
+
+* `"`. Quotation mark.
+* `\`. Backslash.
+* `/`. Forward slash.
+* `b`. Backspace.
+* `f`. Formfeed.
+* `n`. Newline.
+* `r`. Carriage return.
+* `t`. Horizontal tab
+* `u` and 4 hexadecimal digits.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/src/Task.hs b/src/Task.hs
new file mode 100644
--- /dev/null
+++ b/src/Task.hs
@@ -0,0 +1,142 @@
+{-# LANGUAGE OverloadedStrings, PatternGuards #-}
+--
+-- Author: Sean Seefried
+-- Date:   Wed 21 Dec 2011
+--
+module Main where
+
+-- library imports
+import Data.Text (Text)
+import qualified Data.Text as T
+import Text.Printf
+import System.Environment (getArgs, getProgName)
+import Control.Monad
+import System.Exit
+import Data.Map (Map)
+import qualified Data.Map as Map
+
+-- friends
+import StringUtils
+import Time
+
+-- The commands
+import StartCmd 
+import ModifyCmd
+import ClearCmd
+import FinishCmd
+import ExportCmd
+import CurrentCmd
+
+import GetOpt
+
+main :: IO ()
+main = do
+  zt <- getZonedTime
+  name <- getProgName
+  args <- getArgs
+  let cmdMap = commandMap name zt
+      dispatch (cmd:argsForCmd) =
+        case Map.lookup cmd cmdMap  of
+          Just cmd -> cmdHandler cmd argsForCmd
+          Nothing -> printf "%s: '%s' is not a command. See '%s --help'.\n" name cmd name
+  when (wantsHelp args) $ do
+    putStr $ topLevelHelp name zt
+    exitWith ExitSuccess
+  let (cmd:restArgs) = args
+  when (cmd == "help" && length restArgs > 0) $ do
+    putStrLn $ helpFor (head restArgs) cmdMap
+    exitWith ExitSuccess
+  -- now dispatch
+  dispatch args
+
+helpFor :: String -> Map String Command -> String
+helpFor cmd cmdMap = case Map.lookup cmd cmdMap of
+  Just cmd -> printf "%s\n\n%s" (cmdDesc cmd) (cmdHelp cmd)
+  Nothing  -> printf "Can't get help for unknown command '%s'" cmd
+
+--------------
+
+data Command = Cmd { cmdId :: String
+                   , cmdDesc :: String
+                   , cmdHelp :: String
+                   , cmdHandler :: [String] -> IO () }
+
+--
+-- Note to maintainer:
+--
+-- The 'cmdHelp' string should not end in a newline.
+--
+commands :: String -> ZonedTime -> [Command]
+commands name zt =
+  [ Cmd "start"
+        "Start a new task"
+        (usageInfo (printf "Usage: %s start [<flags>...]\n\nFlags:" name)
+                   (startCmdOpts zt))
+        (startCmd zt)
+  , Cmd "current"
+        "Describe the current task"
+        (usageInfo (printf "Usage: %s current" name) [])
+        (currentCmd zt)
+  , Cmd "clear"
+        "Clear current task"
+        (printf "Usage: %s clear" name)
+        clearCmd
+  , Cmd "finish"
+        "Finish current task"
+        (usageInfo (printf "Usage: %s finish [<flags>...]\n\nFlags:" name)
+                   (finishCmdOpts zt))
+        (finishCmd zt)
+  , Cmd "modify"
+        "Modify a task entry"
+        (error "not defined")
+        undefined
+  , Cmd "delete"
+        "Delete a task entry"
+        (error "not defined")
+        undefined
+  , Cmd "query"
+        "Query task entries"
+        (error "not defined")
+        undefined
+  , Cmd "export"
+        "Export task data in a variety of formats"
+        (usageInfo (printf "Usage: %s export [<flags>...]\n\nFlags:" name)
+                   (exportCmdOpts zt))
+        (exportCmd zt)
+
+  ]
+
+commandMap :: String -> ZonedTime -> Map String Command
+commandMap name zt = foldl (\m cmd -> Map.insert (cmdId cmd) cmd m) Map.empty (commands name zt)
+
+-----------
+
+topLevelHelp :: String -> ZonedTime -> String
+topLevelHelp name zt = unlines $ [
+    printf "Usage: %s <command> <flags...>" name
+  , ""
+  , "Commands:"
+  ] ++ (indent 2 . twoColumns 4 $ map f $ commands name zt) ++
+  [ ""
+  , printf "See '%s help <command>' for more information on a specific command." name]
+
+ where f cmd = (cmdId cmd, cmdDesc cmd)
+
+wantsHelp :: [String] -> Bool
+wantsHelp args = containsHelp args || length args == 0 || (head args == "help" && length args == 1)
+
+containsHelp :: [String] -> Bool
+containsHelp = any pred
+  where
+    pred s = any (eq s) ["-h", "--help", "-?"]
+    eq s s' = strip s == s'
+------------------------------
+
+test :: IO ()
+test = do
+  zt <- getZonedTime
+  let mtime = parseTaskTime zt "00:23"
+  case mtime of
+    Just time -> printf "Local: %s\nUTC: %s\n"
+                   (show $ utcToZonedTime (zonedTimeZone zt) time) (show time)
+    Nothing    -> return ()
diff --git a/task.cabal b/task.cabal
new file mode 100644
--- /dev/null
+++ b/task.cabal
@@ -0,0 +1,39 @@
+Name:                task
+Version:             0.0.1
+Synopsis:            A command line tool for keeping track of tasks you worked on
+Description:         'task' is a simple command line tool for keeping track of 
+                     tasks you are working on. Tasks are kept in a simple
+                     persistent store. Each task can be tagged with arbitrary
+                     key/value pairs and the results can be exported to CSV files
+                     filtered on said key/value pairs.
+License:             BSD3
+License-file:        LICENSE
+Author:              Sean Seefried
+Maintainer:          sean.seefried@gmail.com
+
+Category:            Network
+Build-type:          Simple
+Cabal-version: >= 1.8
+Extra-Source-Files:  README.md
+
+Source-Repository head
+   type: git
+   location: git://github.com/sseefried/task.git
+
+Executable task
+  Main-is: Task.hs
+  Build-depends: base >= 2 && <= 4.5.0.0,
+                 random,
+                 containers,
+                 text,
+                 time,
+                 filepath,
+                 unix,
+                 directory,
+                 attoparsec,
+                 bytestring,
+                 aeson,
+                 old-locale,
+                 csv-enumerator
+                 
+  hs-source-dirs: src
