UNPKG

@ibm-adw/skill-toolkit

Version:

Developing your own skills with IBM Automation Digital Worker Skill Toolkit

182 lines (143 loc) 7.3 kB
#!/usr/bin/env node /* Licensed Materials - Property of IBM 5737-I23 Copyright IBM Corp. 2019. All Rights Reserved. U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ const { generateAllFiles } = require('./generate-files'); const exec = require('child_process').exec; const fs = require('fs'); const chalk = require('chalk'); const convertArrayIntoStringForDisplay = (array) => { let displayStr = ''; array.forEach((val, i) => { const start = (!i ? '[ ' : ' '); const end = (i === array.length - 1 ? ' ]' : ','); displayStr += start; displayStr += chalk.green(val); displayStr += end; }); return displayStr; }; const createSkill = async (skillProjectRepo, pathSkillProject) => { console.log('\nCreating a new skill project in', chalk.cyan(pathSkillProject)); if (!fs.existsSync(pathSkillProject)) { fs.mkdirSync(pathSkillProject); } console.log('This utility will walk you through creating a skill package for IBM Automation Digital Worker.'); console.log('Let\'s start by configuring your new skill.\n'); console.log('Press ^C at any time to quit.\n'); let onGoing = true; const availableCategories = [ 'act', 'understand', 'decide' ]; const availableLevels = [ 'tech_preview', 'released' ]; const skillData = { packageName: '@scope/my-skill-package-name', name: 'My Skill Name', description: 'This is my skill description.', author: 'me', category: availableCategories[0], level: availableLevels[0] }; async function sh(cmd) { return new Promise(function (resolve, reject) { exec(cmd, (err, stdout, stderr) => { if (err) { reject(err); } else { resolve({ stdout, stderr }); } }); }); } const askQuestion = (readline, question, element, availableValues) => { return new Promise(resolve => { readline.question(question, async (answer) => { if (answer && availableValues && !availableValues.includes(answer)) { console.log(chalk.red('error:'), answer, 'is not a valid value for', element); console.log('Please choose one from:\n', convertArrayIntoStringForDisplay(availableValues)); await askQuestion(readline, question, element, availableValues); } else if (element && answer) { skillData[element] = answer; } resolve(answer); }); }); }; const askAllQuestions = async (readline) => { await askQuestion(readline, `skill package name [${skillData.packageName}]: `, 'packageName'); await askQuestion(readline, `skill name [${skillData.name}]: `, 'name'); await askQuestion(readline, `skill description [${skillData.description}]: `, 'description'); await askQuestion(readline, `skill author [${skillData.author}]: `, 'author'); console.log('\nThe category of your skill can be one of:'); console.log(convertArrayIntoStringForDisplay(availableCategories)); await askQuestion(readline, `skill category [${skillData.category}]: `, 'category', availableCategories); console.log('\nThe level of your skill can be one of:'); console.log(convertArrayIntoStringForDisplay(availableLevels)); await askQuestion(readline, `skill level [${skillData.level}]: `, 'level', availableLevels); console.log('\n',skillData,'\n'); const agree = await askQuestion(readline, 'Is this OK? [yes]: ') || 'yes'; if (agree === 'yes' || agree === 'y') { const sample = await askQuestion(readline, '\nDo you want to generate a sample skill? [yes]: ') || 'yes'; readline.close(); // continue console.log('\nSetting up the project...\nThis can take a while.\n'); generateAllFiles(pathSkillProject, skillProjectRepo, skillData, (sample === 'yes' || sample === 'y')); const { stdout, stderr } = await sh('cd "' + pathSkillProject + '" && npm i'); for (const line of stdout.split('\n')) { if (line !== '') { console.log(chalk.blue('info'), line); } } for (const line of stderr.split('\n')) { if (line !== '') { console.log(chalk.red('error'), line); } } console.log('\nAll set !'); console.log(''); console.log('You can now start implementing your skill at', chalk.yellow(pathSkillProject)); console.log('There, you can run several commands:\n'); console.log(chalk.cyan(' npm run lint')); console.log(chalk.white(' Check that your code is correctly formatted.\n')); console.log(chalk.cyan(' npm run test')); console.log(chalk.white(' Start the test script.\n')); console.log(chalk.cyan(' npm pack')); console.log(chalk.white(' Generate a tar.gz when your skill is ready.\n')); console.log(''); console.log('You can use the IBM Automation Digital Worker skill test kit.'); console.log('It provides a user interface that will guide you in implementing and testing your skill.'); console.log('In two different terminal windows, run:\n'); console.log(chalk.cyan(' npx adw-launch-server ' + skillProjectRepo), chalk.blue('[SERVER_PORT]')); console.log(chalk.white(' Launches the server side of the IBM Automation Digital Worker test kit to serve your skill located in folder'), chalk.green(skillProjectRepo), chalk.white('.')); console.log(chalk.blue(' (optional)'), chalk.white('[SERVER_PORT] is the port where the skill endpoint is available. If not specified, the default is 8888.\n')); console.log(chalk.cyan(' npx adw-launch-client'), chalk.blue('[CLIENT_PORT] [SERVER_PORT]')); console.log(chalk.white(' Launches the user interface of the IBM Automation Digital Worker test kit.')); console.log(chalk.blue(' (optional)'), chalk.white('[CLIENT_PORT] is the port where the test kit client application is running. If not specified, the default is 3000.')); console.log(chalk.blue(' (optional)'), chalk.white('[SERVER_PORT] is the port where the skill endpoint is available and must correspond to the one you provided when you launched the server. If not specified, the default is 8888. \n')); return false; } else { console.log('Aborted.'); console.log('Let\'s start and configure your skill again.'); return true; } }; const readline = require('readline').createInterface({ input: process.stdin, output: process.stdout }); while (onGoing) { onGoing = await askAllQuestions(readline); } }; module.exports = { createSkill };