`ao-cli` (alias `ao`) is a command-line interface (CLI) that helps you install, use, and configure the Autonomous Organization (AO). `ao-cli` is a Node/JavaScript CLI tool that wraps the functionality of Alchemy, AO administration, plus key AO features into one convenient interface. Command-line social networking.
`ao-cli` (alias `ao`) is a command-line interface (CLI) that helps you install, use, and configure the Autonomous Organization (AO). Command-line social networking for hackers.
To run immediately:
@ -10,10 +10,46 @@ To install:
`npm i -g @autonomousorganization/ao-cli`
Then you can run with `ao-cli`. (Inside the menu you will find an option to add 'ao' as a shortcut.)
Then you can run with `ao-cli`. (In the menus you will find an option to add `ao` as an alias.)
### Version History
## Features
These features work right now:
* Browse the [AO User Manual](https://git.coalitionofinvisiblecolleges.org/autonomousorganization/ao-manual) and automatically download and keep it updated
* Manages your AO configuration file for you
* Wraps the functionality of (some of) Zen's Alchemy suite of scripts (system configuration, AO installation)
* `ao-cli` can self-update to the newest version
* Run AO unit tests to verify the up-to-spec functioning of the system's running AO API server
## Upcoming Features
These features are planned and many are mocked up in the menus:
* Join the AO .onion bootstrapping network and find public AO chatrooms p2p over tor
* Operate essential AO client features (like creating and sending cards p2p via tor)
* Easily install and configure your AO server installation
* Easily use hardware-owner-only god-mode features for your AO server including resetting any password or deleting any member
* Easily monitor your AO server status and start/stop the service
* Easily switch between serving different AO frontends: `ao-svelte`, `ao-3` (Vue), or `ao-react`
* Easily install/uninstall and turn on/off option AO features
* Easily update all your remote AOs at once
* Easily install your preferred flavor of Unix on any unsecured Windows computer given its IP address (j/k)
* Full interactive wizard to walk you through setting up and connecting new AO hardware resources to your AO server
## Important Locations
* `~/.ao/` Your AO saved data folder
* `~/.ao/database.sqlite3` Location of your AO database (copy to back up)
* `~/ao-cli/` Typical location for `ao-cli`
* `~/ao-svelte/` Typical location for `ao-svelte`
* `~/ao-3/` Typical location for `ao-3`
* `~/.ao/ao-manual/` Typical location of the AO manual (Markdown files)
* `~/Alchemy/` Typical location of Zen's Alchemy
## Version History
* 0.0.8 Added self-update feature and --version/-v arg
* 0.0.6 User manual downloads and updates automatically from [official ao-manual repo](https://git.coalitionofinvisiblecolleges.org/autonomousorganization/ao-manual)
// These should become .env variables that are loaded intelligently
letdistro
@ -32,15 +35,13 @@ function exitIfRoot() {
// Prints the AO Main Menu and executes the user's choice
asyncfunctionmainMenu(){
console.log(`\n${headerStyle('AO Main Menu')}\n`)
constmainMenuChoices=[
'Chat',
'Alchemy',
'Deck',
letmainMenuChoices=[
'AO',
'Features',
'Admin',
'Tests',
'Alchemy',
'Manual',
'Log Out',
'Exit',
'Exit'
]
constanswer=awaitinquirer.prompt({
name:'main_menu',
@ -50,20 +51,17 @@ async function mainMenu() {
pageSize:mainMenuChoices.length
})
switch(answer.main_menu){
case'Chat':
while(awaitchatMenu()){}
case'AO':
while(awaituseAoMenu()){}
break
case'Alchemy':
while(awaitalchemyMenu()){}
break
case'Deck':
awaittodoList('My Todo List',['Add full AO install process to ao-cli in convenient format','Add AO server unit tests to ao-cli','Get groceries','Play music every day'])
case'Features':
while(awaitfeaturesMenu()){}
break
case'Admin':
while(awaitadminMenu()){}
break
case'Tests':
while(awaittestsMenu()){}
case'Alchemy':
while(awaitalchemyMenu()){}
break
case'Manual':
if(!isFolder(AO_MANUAL_PATH)){
@ -78,14 +76,11 @@ async function mainMenu() {
updateManual()
}
awaitprintManualPage(AO_MANUAL_PATH)// Fencepost case - print overview page
letpreviousChoice=0
letpreviousChoice
do{
previousChoice=awaitmanualFolderAsMenu(AO_MANUAL_PATH,'AO User Manual','Back to Main Menu',previousChoice+1)
}while(previousChoice!==false)
break
case'Log Out':
awaitspinnerWait('Logging out... (just kidding)')
break
case'Exit':
farewell()
awaitsleep(310)
@ -94,6 +89,50 @@ async function mainMenu() {
returntrue
}
// Prints the Use AO Menu and executes the user's choice
awaittodoList('My Todo List',['Add full AO install process to ao-cli in convenient format','Add AO server unit tests to ao-cli','Get groceries','Play music every day'])
break
case'Log In':
console.log('\nao-cli will use the AO API to log into the AO server at',(aoEnv('AO_CLI_TARGET_HOSTNAME')||AO_DEFAULT_HOSTNAME)+'.')
awaitloginPrompt()
break
case'Log Out':
awaitlogout()
//await spinnerWait('Logging out...')
break
case'Back to Main Menu':
returnfalse
}
returntrue
}
// Prints a menu that allows you to join the global AO chatrooms
letpublicBootstrapStarted=false
asyncfunctionchatMenu(){
@ -159,6 +198,7 @@ async function chatMenu() {
}
// Prints the AO Admin Menu and executes the user's choice
// Maybe Alchemy menu should be installation and update, and admin menu should be more configuration & AO member admin
asyncfunctionadminMenu(){
console.log(`\n${headerStyle('AO Admin Menu')}`)
constadminChoices=[
@ -166,12 +206,13 @@ async function adminMenu() {
'Update ao-cli',
'Check AO install',
'Update AO',
'Configure AO features',
'Switch AO target server',
'Switch AO database',
'Import/Export state/decks',
'Check AO service',
'Watch logs now',
'Start/Stop AO service',
'Tests',
'Back to Main Menu'
]
constanswer=awaitinquirer.prompt({
@ -190,9 +231,7 @@ async function adminMenu() {
break
case'Check AO install':
case'Update AO':
case'Configure AO features':
while(awaitfeaturesMenu()){}
break
case'Switch AO target server':
case'Switch AO database':
case'Import/Export state/decks':
case'Check AO service':
@ -200,6 +239,9 @@ async function adminMenu() {
case'Start/Stop AO service':
console.log("Not yet implemented.")
break
case'Tests':
while(awaittestsMenu()){}
break
default:
returnfalse
}
@ -262,21 +304,29 @@ async function alchemyMenu() {
// Prints the Configure AO Features menu and executes the user's choice
asyncfunctionfeaturesMenu(){
console.log(`\n${headerStyle('Configure AO Features')}`)
conststatus={
off:' '+chalk.grey('Off')+' ',
ins:chalk.yellow('Installed')+' ',
ena:' '+greenChalk('Enabled')+' ',
run:' '+greenChalk('Running')+' ',
err:' '+chalk.red('Error')+' '
}
letwidest=9
constfeatures=[
'nginx host AO publicly over the world wide web',
'SSL/Certbot HTTPS for public web AO',
'Tor connect AOs p2p',
'Bitcoin payments',
'Lightning payments',
'Jitsi secure video chat',
'Signal notifications',
'File hosting file attachments on cards',
'youtube-dl cache web videos',
'Borg backup',
'Encryption serverside secret messages',
'Themes custom themes',
'Glossary custom glossary',
'Jubilee monthly points creation event',
`Tor ${status.run} connect AOs p2p`,
`Bitcoin ${status.run} payments`,
`Lightning ${status.ins} payments`,
`nginx ${status.ins} host AO publicly over the world wide web`,
`SSL/Certbot ${status.ins} HTTPS for public web AO`,
`Jitsi ${status.err} secure video chat`,
`Signal ${status.off} notifications`,
`File hosting ${status.err} file attachments on cards`,
console.log('\nao-cli self-updated automatically from version',beforeVersionNumber,'to version',afterVersionNumber,'from the official npm repository.')
// Different sets of messages that can be randomly selected from
constwelcomeMessages=[
@ -22,7 +23,9 @@ const welcomeMessages = [
`You are offered a choice between two pills. However, you have secretly built up an immunity to both pills, and trick your opponent into taking one. Inconceviably, you are in ${theAO}.`,
`A young man with spiky hair and golden skin appears before you in a halo of light. He guides you to ${theAO}.`,
`You enter a gap between two hedges and, after struggling through the brush, emerge into a sunny estate garden. You've found the AO.`,
`You find a small animal burrow dug near the riverside. Crawling in, you find a network of caves that lead to the AO.`
`You find a small animal burrow dug-out near the riverside. Crawling in, you find a network of caves that lead to ${theAO}.`,
`You receive a handwritten letter in the mail, which reads, in fine calligraphy:, "Dear —, You are in ${theAO}."`,
`An unexpected calm settles over you. The ${greenChalk.bold('AO')} is here: Here is ${theAO}.`