koishi-plugin-terminal 1.0.0 → 1.0.1

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/lib/index.d.ts CHANGED
@@ -3,9 +3,9 @@ import * as pty from "node-pty";
3
3
  export declare const name = "terminal";
4
4
  export interface Config {
5
5
  admin?: Array<string>;
6
+ auth?: number;
6
7
  root?: string;
7
8
  shell?: string;
8
- encoding?: string;
9
9
  timeout?: number;
10
10
  cols?: number;
11
11
  rows?: number;
package/lib/index.js CHANGED
@@ -40,14 +40,14 @@ var pty = __toESM(require("node-pty"));
40
40
  var import_node_timers = require("node:timers");
41
41
  var name = "terminal";
42
42
  var Config = import_koishi.Schema.object({
43
- admin: import_koishi.Schema.array(String).description("超级管理员用户,具有绝对权限。").default([]),
44
- root: import_koishi.Schema.string().description("初始工作路径。").default(process.env.HOME),
45
- shell: import_koishi.Schema.string().description("Shell路径。留空则自动检测系统默认Shell。"),
46
- encoding: import_koishi.Schema.string().description("输出内容编码。").default("utf8"),
47
- timeout: import_koishi.Schema.number().description("超时时长。").default(import_koishi.Time.minute),
43
+ admin: import_koishi.Schema.array(String).description("超级管理员用户名单").default([]),
44
+ auth: import_koishi.Schema.number().description("使用本插件所需的最低权限,此外,用户也需要在超级管理员名单中。").min(1).max(4).step(1).default(4),
45
+ root: import_koishi.Schema.string().description("初始工作路径").default(process.env.HOME),
46
+ shell: import_koishi.Schema.string().description("Shell路径,留空则自动检测系统默认Shell"),
47
+ timeout: import_koishi.Schema.number().description("超时时长").default(import_koishi.Time.minute),
48
48
  cols: import_koishi.Schema.number().description("终端列数").default(80),
49
49
  rows: import_koishi.Schema.number().description("终端行数").default(24),
50
- maxOutputLength: import_koishi.Schema.number().description("单次发送最大输出长度。").default(1800)
50
+ maxOutputLength: import_koishi.Schema.number().description("单次发送最大输出长度").default(16384)
51
51
  });
52
52
  function resolveShell(shell) {
53
53
  if (shell) return shell;
@@ -63,11 +63,12 @@ function resolveShell(shell) {
63
63
  }
64
64
  __name(resolveShell, "resolveShell");
65
65
  function stripAnsi(input) {
66
- return input.replace(
66
+ const text = input.replace(
67
67
  // eslint-disable-next-line no-control-regex
68
68
  /\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g,
69
69
  ""
70
70
  );
71
+ return text.replace(/\r\n/g, "\n").split("\n").map((line) => line.split("\r").at(-1)).join("\n");
71
72
  }
72
73
  __name(stripAnsi, "stripAnsi");
73
74
  function getKey(session) {
@@ -79,7 +80,6 @@ function apply(ctx, config) {
79
80
  const allowedUsers = config.admin;
80
81
  function sendCommand(shellSession, command) {
81
82
  shellSession.terminal.write(command + "\r");
82
- shellSession.terminal.write("pwd\r");
83
83
  }
84
84
  __name(sendCommand, "sendCommand");
85
85
  function initSession(session, key) {
@@ -101,7 +101,7 @@ function apply(ctx, config) {
101
101
  shellSession.buffer = "";
102
102
  if (!output) return;
103
103
  const text = output.length > config.maxOutputLength ? output.slice(0, config.maxOutputLength - 1) + "\n ...Truncated output" : output;
104
- await session.send(text + "$");
104
+ await session.send(text);
105
105
  }, "flush");
106
106
  const dataDisposable = terminal.onData((data) => {
107
107
  shellSession.buffer += data;
@@ -109,7 +109,8 @@ function apply(ctx, config) {
109
109
  shellSession.timer = setTimeout(flush, 300);
110
110
  });
111
111
  const exitDisposable = terminal.onExit(async () => {
112
- cleanupSession(shellSession, key);
112
+ flush();
113
+ cleanupSession(shellSession, key, false);
113
114
  await session.send("Shell exited.");
114
115
  });
115
116
  shellSession.disposables.push(dataDisposable, exitDisposable);
@@ -117,14 +118,20 @@ function apply(ctx, config) {
117
118
  return shellSession;
118
119
  }
119
120
  __name(initSession, "initSession");
120
- function cleanupSession(shellSession, key) {
121
+ function cleanupSession(shellSession, key, kill = true) {
121
122
  map.delete(key);
122
- shellSession.disposables.forEach((d) => d.dispose());
123
- shellSession.terminal.kill();
124
123
  if (shellSession.timer) (0, import_node_timers.clearTimeout)(shellSession.timer);
124
+ shellSession.disposables.forEach((d) => d.dispose());
125
+ shellSession.disposables.length = 0;
126
+ if (kill) {
127
+ try {
128
+ shellSession.terminal.kill();
129
+ } catch {
130
+ }
131
+ }
125
132
  }
126
133
  __name(cleanupSession, "cleanupSession");
127
- ctx.command("shell [command:text]", "Start a persistent shell session", { authority: 4 }).option("terminate", "-t Terminate current shell session").usage("After start up, regular user messages will be sent to shell process.").example("shell echo Operating System: Three Easy Pieces > qljj.txt").action(async ({ session, options }, command) => {
134
+ ctx.command("shell [command:text]", "Start a persistent shell session", { authority: 0 }).option("terminate", "-t Terminate current shell session").usage("After start up, regular user messages will be sent to shell process.").example("shell echo Operating System: Three Easy Pieces > qljj.txt").action(async ({ session, options }, command) => {
128
135
  if (!allowedUsers.includes(session.userId)) {
129
136
  return "Unauthorized user.";
130
137
  }
@@ -132,7 +139,7 @@ function apply(ctx, config) {
132
139
  if (options.terminate) {
133
140
  const current2 = map.get(key);
134
141
  if (!current2) return "There doesn't exist running shell session.";
135
- cleanupSession(current2, key);
142
+ cleanupSession(current2, key, true);
136
143
  return "Shell session terminated.";
137
144
  }
138
145
  let current = map.get(key);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-terminal",
3
- "description": "Persistent terminal interface to a shell session over QQ.",
4
- "version": "1.0.0",
3
+ "description": "通过 QQ 运行持久的 Shell 终端",
4
+ "version": "1.0.1",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
@@ -18,7 +18,8 @@
18
18
  "terminal",
19
19
  "cmd",
20
20
  "bash",
21
- "zsh"
21
+ "zsh",
22
+ "command"
22
23
  ],
23
24
  "repository": {
24
25
  "type": "git",