update the initialization step to include the initial top-level npm install
diff --git a/client/lib/init.js b/client/lib/init.js
index 07a8ed6..672cc68 100644
--- a/client/lib/init.js
+++ b/client/lib/init.js
@@ -15,30 +15,56 @@
  */
 
 var fs = require('fs'),
-    exec = require('child_process').execSync,
+    exec = require('child_process').exec,
     path = require('path'),
-    MARKER = '.initDone';
+    MARKER = '.initDone',
+    nodejs6_deps = path.join('deps', 'nodejs6');
 
 function touch() {
     fs.closeSync(fs.openSync(MARKER, 'w'));
 }
 function initDone() {
     try {
-	return fs.statSync(MARKER).isFile();
+	return fs.statSync(MARKER).isFile()
+	    && fs.statSync('node_modules').isDirectory()
+	    && fs.statSync(nodejs6_deps).isDirectory();
     } catch (e) {
 	return false;
     }
 }
 
-function doInit() {
-    console.log('Doing one-time init');
-    exec('npm install', { cwd: path.join('deps', 'nodejs6'), stdio: 'inherit' });
-    
-    touch();
-}
-
 exports.init = function init() {
-    if (!initDone()) {
-	doInit();
-    }
-};
+    return new Promise((resolve, reject) => {
+	if (initDone()) {
+	    return resolve();
+	}
+
+	console.log('>>> Please be patient while we finish up the installation of the OpenWhisk Debugger.');
+	console.log('>>> This may take 60-90 seconds');
+
+	var dots = setInterval(function() {
+	    process.stdout.write('.');
+	}, 1000);
+    
+	exec('npm install', { cwd: process.cwd() /*, stdio: 'inherit'*/ }, (err) => {
+	    if (err) {
+		return reject(err);
+	    }
+	    
+	    exec('npm install', { cwd: nodejs6_deps/*, stdio: 'inherit'*/ }, (err) => {
+		if (err) {
+		    return reject(err);
+		}
+		
+		touch();
+		clearInterval(dots);
+
+		console.log();
+		console.log('>>> Great! The one-time initialization has completed.');
+		console.log();
+
+		resolve();
+	    });
+	});
+    });
+}
diff --git a/client/lib/main.js b/client/lib/main.js
new file mode 100644
index 0000000..e3721bb
--- /dev/null
+++ b/client/lib/main.js
@@ -0,0 +1,180 @@
+var argv = require('argv'),
+    repl = require('./repl').repl,
+    colors = require('colors'),
+    events = require('events'),
+    package = require('../package.json'),
+    eventBus = new events.EventEmitter(),
+    WebSocket = require('ws'),
+    debugNodeJS = require('./debug-nodejs').debug,
+    debugSwift = require('./debug-swift').debug,
+    expandHomeDir = require('expand-home-dir'),
+    propertiesParser = require('properties-parser'),
+
+    api = {
+	host: 'https://openwhisk.ng.bluemix.net',
+	path: '/api/v1'
+    },
+    broker = {
+	host: 'https://owdbg-broker.mybluemix.net',
+	path: '/ws/client/register'
+    };
+
+exports.main = function() {
+
+var commandLineOptionsConfig = [
+    {name: 'use-cli-debugger', short: 'c', type: 'string', description: 'Favor the CLI for debug sessions over a GUI'},
+    {name: 'no-color', type: 'string', description: 'Avoid using console colors'} // this comes from the colors module
+];
+argv.info('Usage: wskdb [attachTo] [options...]'.red + '\n\nWhere each option is one of the following:');
+argv.version(package.version);
+var commandLineOptions = argv
+    .option(commandLineOptionsConfig)
+    .run()
+    .options;
+
+var ws = new WebSocket(broker.host + broker.path);
+
+ws.on('open', function open() {
+    console.log('Welcome to the OpenWhisk Debugger'.red);
+
+    if (commandLineOptions) {
+	for (var x in commandLineOptions) {
+	    if (commandLineOptions.hasOwnProperty(x)) {
+		console.log(('    + ' + commandLineOptionsConfig.find((o) => o.name === x).description).dim);
+	    }
+	}
+    }
+    console.log();
+
+    var wskprops = propertiesParser.read(expandHomeDir('~/.wskprops'));
+    var key = wskprops.AUTH;
+    ws.send(JSON.stringify({
+	type: 'init',
+	key: key
+    }));
+
+    var keepAlive = setInterval(function poke() {
+	ws.send(JSON.stringify({
+	    type: 'keep-alive'
+	}));
+    }, 5000);
+
+    process.on('exit', function onExit() {
+	try {
+	    console.log('Goodbye!'.red);
+	    clearInterval(keepAlive);
+	    
+	    ws.send(JSON.stringify({
+		type: 'disconnect'
+	    }, function ack() {
+		ws.close();
+	    }));
+	} catch (e) {
+	}
+    });
+
+    //
+    // does the user want to attach to an action right up front?
+    //
+    var attachTo;
+    try {
+	attachTo = process.argv.slice(2).find(arg => {
+	    arg = arg.replace(/-/g, '');
+	    return !commandLineOptions.hasOwnProperty(arg) // not a long option
+		&& !commandLineOptionsConfig.find(opt => opt.short === arg); // and not a short option
+	});
+    } catch (e) {
+	// uncomment this for debugging:
+	// console.error('error',e);
+    }
+
+    repl(wskprops, eventBus, attachTo);
+});
+
+ws.on('close', function() {
+    console.log('Remote connection closed');
+});
+ 
+ws.on('message', function(data, flags) {
+    //console.log('MESSAGE ' + data + ' ||| ' + JSON.stringify(flags));
+    
+    //
+    // flags.binary will be set if a binary data is received. 
+    // flags.masked will be set if the data was masked.
+    //
+    try {
+	var message = JSON.parse(data);
+	switch (message.type) {
+	case 'invoke':
+	    console.log('Debug session requested');
+	    //console.log(JSON.stringify(message, undefined, 4));
+
+	    var done = function done(err, result) {
+		// console.log('Finishing up this debug session');
+
+		ws.send(JSON.stringify({
+		    type: err ? 'circuit-breaker' : 'end',
+		    key: message.key,
+		    activationId: message.activationId,
+		    result: result
+		}));
+
+		//ws.close();
+	    };
+	    var circuitBreaker = function circuitBreaker() {
+		ws.send(JSON.stringify({
+			type: 'circuit-breaker',
+			key: message.key,
+			activationId: message.activationId,
+		}));
+	    };
+
+	    if (message.onDone_trigger) {
+		if (message.action && message.action.exec) {
+		    var kind = message.action.exec.kind;
+		    var debugHandler;
+		    
+		    if (!kind || kind.indexOf('nodejs') >= 0) {
+			// !kind because nodejs is the default
+			debugHandler = debugNodeJS;
+		    } else if (kind.indexOf('swift') >= 0) {
+			debugHandler = debugSwift;
+		    }
+
+		    if (debugHandler) {
+			debugHandler(message, ws, { trigger: message.onDone_trigger }, done, commandLineOptions, eventBus);
+		    } else {
+			console.error('Unable to complete invocation, because this action\'s kind is not yet handled: ' + kind);
+			circuitBreaker();
+		    }
+
+		} else {
+		    console.error('Unable to complete invocation: no action code to debug');
+		    circuitBreaker();
+		}
+	    } else {
+		console.error('Unable to complete invocation: no onDone_trigger specified');
+		circuitBreaker();
+	    }
+
+	    break;
+	}
+    } catch (e) {
+	console.log(e);
+    }
+});
+
+/*
+sending binary data 
+ws.on('open', function open() {
+  var array = new Float32Array(5);
+ 
+  for (var i = 0; i < array.length; ++i) {
+    array[i] = i / 2;
+  }
+ 
+  ws.send(array, { binary: true, mask: true });
+});
+*/
+
+};
diff --git a/client/wskdb.js b/client/wskdb.js
index 0c61e79..0fc0081 100644
--- a/client/wskdb.js
+++ b/client/wskdb.js
@@ -14,183 +14,6 @@
  * limitations under the License.
  */
 
-var argv = require('argv'),
-    init = require('./lib/init').init,
-    repl = require('./lib/repl').repl,
-    colors = require('colors'),
-    events = require('events'),
-    package = require('./package.json'),
-    eventBus = new events.EventEmitter(),
-    WebSocket = require('ws'),
-    debugNodeJS = require('./lib/debug-nodejs').debug,
-    debugSwift = require('./lib/debug-swift').debug,
-    expandHomeDir = require('expand-home-dir'),
-    propertiesParser = require('properties-parser'),
-
-    api = {
-	host: 'https://openwhisk.ng.bluemix.net',
-	path: '/api/v1'
-    },
-    broker = {
-	host: 'https://owdbg-broker.mybluemix.net',
-	path: '/ws/client/register'
-    };
-
-init();
-
-var commandLineOptionsConfig = [
-    {name: 'use-cli-debugger', short: 'c', type: 'string', description: 'Favor the CLI for debug sessions over a GUI'},
-    {name: 'no-color', type: 'string', description: 'Avoid using console colors'} // this comes from the colors module
-];
-argv.info('Usage: wskdb [attachTo] [options...]'.red + '\n\nWhere each option is one of the following:');
-argv.version(package.version);
-var commandLineOptions = argv
-    .option(commandLineOptionsConfig)
-    .run()
-    .options;
-
-var ws = new WebSocket(broker.host + broker.path);
-
-ws.on('open', function open() {
-    console.log('Welcome to the OpenWhisk Debugger'.red);
-
-    if (commandLineOptions) {
-	for (var x in commandLineOptions) {
-	    if (commandLineOptions.hasOwnProperty(x)) {
-		console.log(('    + ' + commandLineOptionsConfig.find((o) => o.name === x).description).dim);
-	    }
-	}
-    }
-    console.log();
-
-    var wskprops = propertiesParser.read(expandHomeDir('~/.wskprops'));
-    var key = wskprops.AUTH;
-    ws.send(JSON.stringify({
-	type: 'init',
-	key: key
-    }));
-
-    var keepAlive = setInterval(function poke() {
-	ws.send(JSON.stringify({
-	    type: 'keep-alive'
-	}));
-    }, 5000);
-
-    process.on('exit', function onExit() {
-	try {
-	    console.log('Goodbye!'.red);
-	    clearInterval(keepAlive);
-	    
-	    ws.send(JSON.stringify({
-		type: 'disconnect'
-	    }, function ack() {
-		ws.close();
-	    }));
-	} catch (e) {
-	}
-    });
-
-    //
-    // does the user want to attach to an action right up front?
-    //
-    var attachTo;
-    try {
-	attachTo = process.argv.slice(2).find(arg => {
-	    arg = arg.replace(/-/g, '');
-	    return !commandLineOptions.hasOwnProperty(arg) // not a long option
-		&& !commandLineOptionsConfig.find(opt => opt.short === arg); // and not a short option
-	});
-    } catch (e) {
-	// uncomment this for debugging:
-	// console.error('error',e);
-    }
-
-    repl(wskprops, eventBus, attachTo);
-});
-
-ws.on('close', function() {
-    console.log('Remote connection closed');
-});
- 
-ws.on('message', function(data, flags) {
-    //console.log('MESSAGE ' + data + ' ||| ' + JSON.stringify(flags));
-    
-    //
-    // flags.binary will be set if a binary data is received. 
-    // flags.masked will be set if the data was masked.
-    //
-    try {
-	var message = JSON.parse(data);
-	switch (message.type) {
-	case 'invoke':
-	    console.log('Debug session requested');
-	    //console.log(JSON.stringify(message, undefined, 4));
-
-	    var done = function done(err, result) {
-		// console.log('Finishing up this debug session');
-
-		ws.send(JSON.stringify({
-		    type: err ? 'circuit-breaker' : 'end',
-		    key: message.key,
-		    activationId: message.activationId,
-		    result: result
-		}));
-
-		//ws.close();
-	    };
-	    var circuitBreaker = function circuitBreaker() {
-		ws.send(JSON.stringify({
-			type: 'circuit-breaker',
-			key: message.key,
-			activationId: message.activationId,
-		}));
-	    };
-
-	    if (message.onDone_trigger) {
-		if (message.action && message.action.exec) {
-		    var kind = message.action.exec.kind;
-		    var debugHandler;
-		    
-		    if (!kind || kind.indexOf('nodejs') >= 0) {
-			// !kind because nodejs is the default
-			debugHandler = debugNodeJS;
-		    } else if (kind.indexOf('swift') >= 0) {
-			debugHandler = debugSwift;
-		    }
-
-		    if (debugHandler) {
-			debugHandler(message, ws, { trigger: message.onDone_trigger }, done, commandLineOptions, eventBus);
-		    } else {
-			console.error('Unable to complete invocation, because this action\'s kind is not yet handled: ' + kind);
-			circuitBreaker();
-		    }
-
-		} else {
-		    console.error('Unable to complete invocation: no action code to debug');
-		    circuitBreaker();
-		}
-	    } else {
-		console.error('Unable to complete invocation: no onDone_trigger specified');
-		circuitBreaker();
-	    }
-
-	    break;
-	}
-    } catch (e) {
-	console.log(e);
-    }
-});
-
-/*
-sending binary data 
-ws.on('open', function open() {
-  var array = new Float32Array(5);
- 
-  for (var i = 0; i < array.length; ++i) {
-    array[i] = i / 2;
-  }
- 
-  ws.send(array, { binary: true, mask: true });
-});
-*/
-
+require('./lib/init').init()
+    .then(() => require('./lib/main').main())
+    .catch((err) => console.err(err));