code: function() {
  	var hooks = {};
  	return {
  		// ignore hook error
  		ignore: false,
  		// provide async api
  		async: async,
  		/**
  		 * add a new hook
  		 * @param  {String} hook  [hook name]
  		 * @param  {Object} rules [hook trigger rules]
  		 * @return Githook
  		 */
  		hook: function(hook, rules) {
  			if (cfg.AVAILABLE_HOOKS.indexOf(hook) < 0 && !this.ignore) {
  				this.error('hook "' + hook + '" not support');
  			}
  
  			if (!hooks[hook]) {
  				hooks[hook] = new Githook(rules);
  			}
  			return hooks[hook];
  		},
  		/**
  		 * remove hook
  		 * @param  {String} hook [hook name]
  		 */
  		removeHook: function(hook) {
  			if (hooks[hook]) {
  				delete hooks[hook];
  			}
  		},
  		/**
  		 * return all pending hooks
  		 * @return {Array} hook names
  		 */
  		pendingHooks: function() {
  			return Object.keys(hooks);
  		},
  		/**
  		 * trigger Githook
  		 * @param  {String} hook [hook name]
  		 */
  		trigger: function(hook) {
  			hooks[hook] && hooks[hook].trigger.apply(hooks[hook], Array.prototype.slice.call(arguments, 1));
  		},
  		/**
  		 * output error message and exit with ERROR_EXIT
  		 * @param  {String|Error} error 
  		 */
  		error: function(error) {
  			if (error) {
  				console.error(error.toString());
  			}
  			process.exit(cfg.ERROR_EXIT);
  		},
  		/**
  		 * pass immediately
  		 * output notice message and exit with SUCCESS_EXIT
  		 * @param  {[type]} notice [description]
  		 * @return {[type]}        [description]
  		 */
  		pass: function(notice) {
  			if (notice) {
  				console.log('Notice: ' + notice);
  			}
  			process.exit(cfg.SUCCESS_EXIT);
  		}
  	}
  }
docs: set of Githook