hubot 9.1.1 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/package.json +1 -2
- package/src/adapters/shell.js +68 -91
package/README.md
CHANGED
|
@@ -23,6 +23,9 @@ This will create a directory called `myhubot` in the current working directory.
|
|
|
23
23
|
|
|
24
24
|
```sh
|
|
25
25
|
npx hubot --create myhubot --adapter @hubot-friends/hubot-slack
|
|
26
|
+
npx hubot --create myhubot --adapter @hubot-friends/hubot-discord
|
|
27
|
+
npx hubot --create myhubot --adapter @hubot-friends/hubot-ms-teams
|
|
28
|
+
npx hubot --create myhubot --adapter @hubot-friends/hubot-irc
|
|
26
29
|
```
|
|
27
30
|
|
|
28
31
|
Review `scripts/example.mjs`. Create more scripts in the `scripts` folder.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hubot",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.0",
|
|
4
4
|
"author": "hubot",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"github",
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
"url": "https://github.com/hubotio/hubot.git"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"cline": "^0.8.2",
|
|
19
18
|
"coffeescript": "^2.7.0",
|
|
20
19
|
"connect-multiparty": "^2.2.0",
|
|
21
20
|
"express": "^4.18.2",
|
package/src/adapters/shell.js
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const fs = require('fs')
|
|
4
|
-
const readline = require('readline')
|
|
5
|
-
const Stream = require('stream')
|
|
6
|
-
const cline = require('cline')
|
|
7
|
-
|
|
4
|
+
const readline = require('node:readline')
|
|
8
5
|
const Adapter = require('../adapter')
|
|
9
|
-
|
|
10
|
-
const _require = require('../message')
|
|
11
|
-
|
|
12
|
-
const TextMessage = _require.TextMessage
|
|
6
|
+
const { TextMessage } = require('../message')
|
|
13
7
|
|
|
14
8
|
const historySize = process.env.HUBOT_SHELL_HISTSIZE != null ? parseInt(process.env.HUBOT_SHELL_HISTSIZE) : 1024
|
|
15
|
-
|
|
16
9
|
const historyPath = '.hubot_history'
|
|
10
|
+
|
|
11
|
+
const completer = line => {
|
|
12
|
+
const completions = '\\q exit \\? help \\c clear'.split(' ')
|
|
13
|
+
const hits = completions.filter((c) => c.startsWith(line))
|
|
14
|
+
// Show all completions if none found
|
|
15
|
+
return [hits.length ? hits : completions, line]
|
|
16
|
+
}
|
|
17
|
+
const showHelp = () => {
|
|
18
|
+
console.log('usage:')
|
|
19
|
+
console.log('\\q, exit - close shell and exit')
|
|
20
|
+
console.log('\\?, help - show this help')
|
|
21
|
+
console.log('\\c, clear - clear screen')
|
|
22
|
+
}
|
|
23
|
+
|
|
17
24
|
const bold = str => `\x1b[1m${str}\x1b[22m`
|
|
18
25
|
|
|
19
26
|
class Shell extends Adapter {
|
|
@@ -37,32 +44,45 @@ class Shell extends Adapter {
|
|
|
37
44
|
}
|
|
38
45
|
|
|
39
46
|
async run () {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const { readlineInterface, history } = await this.#loadHistory()
|
|
43
|
-
this.cli.history(history)
|
|
44
|
-
this.cli.interact(`${this.robot.name ?? this.robot.alias}> `)
|
|
45
|
-
this.#rl = readlineInterface
|
|
46
|
-
this.emit('connected', this)
|
|
47
|
-
} catch (error) {
|
|
48
|
-
console.log(error)
|
|
47
|
+
if (!fs.existsSync(historyPath)) {
|
|
48
|
+
fs.writeFileSync(historyPath, '')
|
|
49
49
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
super.close()
|
|
54
|
-
// Getting an error message on GitHubt Actions: error: 'this[#rl].close is not a function'
|
|
55
|
-
if (this.#rl?.close) {
|
|
56
|
-
this.#rl.close()
|
|
50
|
+
const stats = fs.statSync(historyPath)
|
|
51
|
+
if (stats.size > historySize) {
|
|
52
|
+
fs.unlinkSync(historyPath)
|
|
57
53
|
}
|
|
58
|
-
this.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
54
|
+
this.#rl = readline.createInterface({
|
|
55
|
+
input: process.stdin,
|
|
56
|
+
output: process.stdout,
|
|
57
|
+
prompt: `${this.robot.name ?? this.robot.alias}> `,
|
|
58
|
+
completer
|
|
59
|
+
})
|
|
60
|
+
this.#rl.on('line', async (line) => {
|
|
61
|
+
const input = line.trim()
|
|
62
|
+
switch (input) {
|
|
63
|
+
case '\\q':
|
|
64
|
+
case 'exit':
|
|
65
|
+
this.#rl.close()
|
|
66
|
+
break
|
|
67
|
+
case '\\?':
|
|
68
|
+
case 'help':
|
|
69
|
+
showHelp()
|
|
70
|
+
break
|
|
71
|
+
case '\\c':
|
|
72
|
+
case 'clear':
|
|
73
|
+
this.#rl.write(null, { ctrl: true, name: 'l' })
|
|
74
|
+
this.#rl.prompt()
|
|
75
|
+
break
|
|
76
|
+
}
|
|
77
|
+
const history = fs.readFileSync(historyPath, 'utf-8').split('\n').reverse()
|
|
78
|
+
this.#rl.history = history
|
|
79
|
+
this.#rl.on('line', line => {
|
|
80
|
+
const input = line.trim()
|
|
81
|
+
if (input.length === 0) return
|
|
82
|
+
fs.appendFile(historyPath, `${input}\n`, err => {
|
|
83
|
+
if (err) console.error(err)
|
|
84
|
+
})
|
|
85
|
+
})
|
|
66
86
|
let userId = process.env.HUBOT_SHELL_USER_ID || '1'
|
|
67
87
|
if (userId.match(/A\d+z/)) {
|
|
68
88
|
userId = parseInt(userId)
|
|
@@ -71,68 +91,25 @@ class Shell extends Adapter {
|
|
|
71
91
|
const userName = process.env.HUBOT_SHELL_USER_NAME || 'Shell'
|
|
72
92
|
const user = this.robot.brain.userForId(userId, { name: userName, room: 'Shell' })
|
|
73
93
|
await this.receive(new TextMessage(user, input, 'messageId'))
|
|
94
|
+
this.#rl.prompt()
|
|
95
|
+
}).on('close', () => {
|
|
96
|
+
process.exit(0)
|
|
74
97
|
})
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (item.length > 0 && item !== 'exit' && item !== 'history') {
|
|
82
|
-
fs.appendFile(historyPath, `${item}\n`, error => {
|
|
83
|
-
if (error) {
|
|
84
|
-
this.robot.emit('error', error)
|
|
85
|
-
}
|
|
86
|
-
})
|
|
87
|
-
}
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
this.cli.on('close', () => {
|
|
91
|
-
let history, i, item, len
|
|
92
|
-
|
|
93
|
-
history = this.cli.history()
|
|
94
|
-
|
|
95
|
-
if (history.length <= historySize) {
|
|
96
|
-
return
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const startIndex = history.length - historySize
|
|
100
|
-
history = history.reverse().splice(startIndex, historySize)
|
|
101
|
-
const fileOpts = {
|
|
102
|
-
mode: 0x180
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const outstream = fs.createWriteStream(historyPath, fileOpts)
|
|
106
|
-
for (i = 0, len = history.length; i < len; i++) {
|
|
107
|
-
item = history[i]
|
|
108
|
-
outstream.write(item + '\n')
|
|
109
|
-
}
|
|
110
|
-
outstream.end()
|
|
111
|
-
})
|
|
98
|
+
try {
|
|
99
|
+
this.#rl.prompt()
|
|
100
|
+
this.emit('connected', this)
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.log(error)
|
|
103
|
+
}
|
|
112
104
|
}
|
|
113
105
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
106
|
+
close () {
|
|
107
|
+
super.close()
|
|
108
|
+
if (this.#rl?.close) {
|
|
109
|
+
this.#rl.close()
|
|
117
110
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
outstream.readable = true
|
|
121
|
-
outstream.writable = true
|
|
122
|
-
const history = []
|
|
123
|
-
const readlineInterface = readline.createInterface({ input: instream, output: outstream, terminal: false })
|
|
124
|
-
return new Promise((resolve, reject) => {
|
|
125
|
-
readlineInterface.on('line', line => {
|
|
126
|
-
line = line.trim()
|
|
127
|
-
if (line.length > 0) {
|
|
128
|
-
history.push(line)
|
|
129
|
-
}
|
|
130
|
-
})
|
|
131
|
-
readlineInterface.on('close', () => {
|
|
132
|
-
resolve({ readlineInterface, history })
|
|
133
|
-
})
|
|
134
|
-
readlineInterface.on('error', reject)
|
|
135
|
-
})
|
|
111
|
+
this.cli.removeAllListeners()
|
|
112
|
+
this.cli.close()
|
|
136
113
|
}
|
|
137
114
|
}
|
|
138
115
|
|