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 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": "9.1.1",
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",
@@ -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
- this.buildCli()
41
- try {
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
- close () {
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.cli.removeAllListeners()
59
- this.cli.close()
60
- }
61
-
62
- buildCli () {
63
- this.cli = cline()
64
-
65
- this.cli.command('*', async input => {
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
- this.cli.command('history', () => {
77
- Array.from(this.cli.history()).map(item => console.log(item))
78
- })
79
-
80
- this.cli.on('history', item => {
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
- async #loadHistory () {
115
- if (!fs.existsSync(historyPath)) {
116
- return new Error('No history available')
106
+ close () {
107
+ super.close()
108
+ if (this.#rl?.close) {
109
+ this.#rl.close()
117
110
  }
118
- const instream = fs.createReadStream(historyPath)
119
- const outstream = new Stream()
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