botmux 1.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/.env.example +24 -0
- package/LICENSE +21 -0
- package/README.en.md +267 -0
- package/README.md +267 -0
- package/dist/adapters/backend/pty-backend.d.ts +13 -0
- package/dist/adapters/backend/pty-backend.d.ts.map +1 -0
- package/dist/adapters/backend/pty-backend.js +39 -0
- package/dist/adapters/backend/pty-backend.js.map +1 -0
- package/dist/adapters/backend/tmux-backend.d.ts +20 -0
- package/dist/adapters/backend/tmux-backend.d.ts.map +1 -0
- package/dist/adapters/backend/tmux-backend.js +30 -0
- package/dist/adapters/backend/tmux-backend.js.map +1 -0
- package/dist/adapters/backend/types.d.ts +19 -0
- package/dist/adapters/backend/types.d.ts.map +1 -0
- package/dist/adapters/backend/types.js +2 -0
- package/dist/adapters/backend/types.js.map +1 -0
- package/dist/adapters/cli/aiden.d.ts +4 -0
- package/dist/adapters/cli/aiden.d.ts.map +1 -0
- package/dist/adapters/cli/aiden.js +63 -0
- package/dist/adapters/cli/aiden.js.map +1 -0
- package/dist/adapters/cli/claude-code.d.ts +4 -0
- package/dist/adapters/cli/claude-code.d.ts.map +1 -0
- package/dist/adapters/cli/claude-code.js +59 -0
- package/dist/adapters/cli/claude-code.js.map +1 -0
- package/dist/adapters/cli/coco.d.ts +4 -0
- package/dist/adapters/cli/coco.d.ts.map +1 -0
- package/dist/adapters/cli/coco.js +46 -0
- package/dist/adapters/cli/coco.js.map +1 -0
- package/dist/adapters/cli/codex.d.ts +4 -0
- package/dist/adapters/cli/codex.d.ts.map +1 -0
- package/dist/adapters/cli/codex.js +47 -0
- package/dist/adapters/cli/codex.js.map +1 -0
- package/dist/adapters/cli/registry.d.ts +13 -0
- package/dist/adapters/cli/registry.d.ts.map +1 -0
- package/dist/adapters/cli/registry.js +42 -0
- package/dist/adapters/cli/registry.js.map +1 -0
- package/dist/adapters/cli/types.d.ts +39 -0
- package/dist/adapters/cli/types.d.ts.map +1 -0
- package/dist/adapters/cli/types.js +2 -0
- package/dist/adapters/cli/types.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +245 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +39 -0
- package/dist/config.js.map +1 -0
- package/dist/core/command-handler.d.ts +11 -0
- package/dist/core/command-handler.d.ts.map +1 -0
- package/dist/core/command-handler.js +322 -0
- package/dist/core/command-handler.js.map +1 -0
- package/dist/core/cost-calculator.d.ts +12 -0
- package/dist/core/cost-calculator.d.ts.map +1 -0
- package/dist/core/cost-calculator.js +61 -0
- package/dist/core/cost-calculator.js.map +1 -0
- package/dist/core/scheduler.d.ts +38 -0
- package/dist/core/scheduler.d.ts.map +1 -0
- package/dist/core/scheduler.js +221 -0
- package/dist/core/scheduler.js.map +1 -0
- package/dist/core/session-manager.d.ts +13 -0
- package/dist/core/session-manager.d.ts.map +1 -0
- package/dist/core/session-manager.js +125 -0
- package/dist/core/session-manager.js.map +1 -0
- package/dist/core/types.d.ts +29 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/worker-pool.d.ts +26 -0
- package/dist/core/worker-pool.d.ts.map +1 -0
- package/dist/core/worker-pool.js +261 -0
- package/dist/core/worker-pool.js.map +1 -0
- package/dist/daemon.d.ts +3 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +344 -0
- package/dist/daemon.js.map +1 -0
- package/dist/im/lark/card-builder.d.ts +18 -0
- package/dist/im/lark/card-builder.d.ts.map +1 -0
- package/dist/im/lark/card-builder.js +194 -0
- package/dist/im/lark/card-builder.js.map +1 -0
- package/dist/im/lark/card-handler.d.ts +9 -0
- package/dist/im/lark/card-handler.d.ts.map +1 -0
- package/dist/im/lark/card-handler.js +131 -0
- package/dist/im/lark/card-handler.js.map +1 -0
- package/dist/im/lark/client.d.ts +23 -0
- package/dist/im/lark/client.d.ts.map +1 -0
- package/dist/im/lark/client.js +259 -0
- package/dist/im/lark/client.js.map +1 -0
- package/dist/im/lark/event-dispatcher.d.ts +34 -0
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -0
- package/dist/im/lark/event-dispatcher.js +195 -0
- package/dist/im/lark/event-dispatcher.js.map +1 -0
- package/dist/im/lark/message-parser.d.ts +45 -0
- package/dist/im/lark/message-parser.d.ts.map +1 -0
- package/dist/im/lark/message-parser.js +132 -0
- package/dist/im/lark/message-parser.js.map +1 -0
- package/dist/im/types.d.ts +78 -0
- package/dist/im/types.d.ts.map +1 -0
- package/dist/im/types.js +2 -0
- package/dist/im/types.js.map +1 -0
- package/dist/index-daemon.d.ts +3 -0
- package/dist/index-daemon.d.ts.map +1 -0
- package/dist/index-daemon.js +21 -0
- package/dist/index-daemon.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/scheduler.d.ts +38 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +221 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +23 -0
- package/dist/server.js.map +1 -0
- package/dist/services/lark-client.d.ts +22 -0
- package/dist/services/lark-client.d.ts.map +1 -0
- package/dist/services/lark-client.js +238 -0
- package/dist/services/lark-client.js.map +1 -0
- package/dist/services/lark-ws.d.ts +5 -0
- package/dist/services/lark-ws.d.ts.map +1 -0
- package/dist/services/lark-ws.js +79 -0
- package/dist/services/lark-ws.js.map +1 -0
- package/dist/services/message-queue.d.ts +9 -0
- package/dist/services/message-queue.d.ts.map +1 -0
- package/dist/services/message-queue.js +77 -0
- package/dist/services/message-queue.js.map +1 -0
- package/dist/services/message-router.d.ts +8 -0
- package/dist/services/message-router.d.ts.map +1 -0
- package/dist/services/message-router.js +73 -0
- package/dist/services/message-router.js.map +1 -0
- package/dist/services/project-scanner.d.ts +12 -0
- package/dist/services/project-scanner.d.ts.map +1 -0
- package/dist/services/project-scanner.js +109 -0
- package/dist/services/project-scanner.js.map +1 -0
- package/dist/services/schedule-store.d.ts +14 -0
- package/dist/services/schedule-store.d.ts.map +1 -0
- package/dist/services/schedule-store.js +89 -0
- package/dist/services/schedule-store.js.map +1 -0
- package/dist/services/session-store.d.ts +8 -0
- package/dist/services/session-store.d.ts.map +1 -0
- package/dist/services/session-store.js +93 -0
- package/dist/services/session-store.js.map +1 -0
- package/dist/tools/close-session.d.ts +22 -0
- package/dist/tools/close-session.d.ts.map +1 -0
- package/dist/tools/close-session.js +38 -0
- package/dist/tools/close-session.js.map +1 -0
- package/dist/tools/create-session.d.ts +28 -0
- package/dist/tools/create-session.d.ts.map +1 -0
- package/dist/tools/create-session.js +40 -0
- package/dist/tools/create-session.js.map +1 -0
- package/dist/tools/get-thread-messages.d.ts +26 -0
- package/dist/tools/get-thread-messages.d.ts.map +1 -0
- package/dist/tools/get-thread-messages.js +33 -0
- package/dist/tools/get-thread-messages.js.map +1 -0
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +10 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/react-to-message.d.ts +41 -0
- package/dist/tools/react-to-message.d.ts.map +1 -0
- package/dist/tools/react-to-message.js +30 -0
- package/dist/tools/react-to-message.js.map +1 -0
- package/dist/tools/send-to-thread.d.ts +24 -0
- package/dist/tools/send-to-thread.d.ts.map +1 -0
- package/dist/tools/send-to-thread.js +83 -0
- package/dist/tools/send-to-thread.js.map +1 -0
- package/dist/tools/wait-for-reply.d.ts +17 -0
- package/dist/tools/wait-for-reply.d.ts.map +1 -0
- package/dist/tools/wait-for-reply.js +65 -0
- package/dist/tools/wait-for-reply.js.map +1 -0
- package/dist/types.d.ts +85 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/card-builder.d.ts +16 -0
- package/dist/utils/card-builder.d.ts.map +1 -0
- package/dist/utils/card-builder.js +183 -0
- package/dist/utils/card-builder.js.map +1 -0
- package/dist/utils/idle-detector.d.ts +21 -0
- package/dist/utils/idle-detector.d.ts.map +1 -0
- package/dist/utils/idle-detector.js +95 -0
- package/dist/utils/idle-detector.js.map +1 -0
- package/dist/utils/logger.d.ts +7 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +22 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/message-parser.d.ts +45 -0
- package/dist/utils/message-parser.d.ts.map +1 -0
- package/dist/utils/message-parser.js +132 -0
- package/dist/utils/message-parser.js.map +1 -0
- package/dist/utils/terminal-renderer.d.ts +39 -0
- package/dist/utils/terminal-renderer.d.ts.map +1 -0
- package/dist/utils/terminal-renderer.js +186 -0
- package/dist/utils/terminal-renderer.js.map +1 -0
- package/dist/worker.d.ts +3 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +411 -0
- package/dist/worker.js.map +1 -0
- package/ecosystem.config.cjs +15 -0
- package/package.json +60 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/** Spinner frames — animate while CLI is working */
|
|
2
|
+
const SPINNER_RE = /[·✢✳✶✻✽]/;
|
|
3
|
+
/** Default quiescence timeout (ms) — idle if PTY silent + no recent spinner */
|
|
4
|
+
const QUIESCENCE_MS = 2_000;
|
|
5
|
+
/** Spinner guard — don't declare idle if spinner seen within this window */
|
|
6
|
+
const SPINNER_GUARD_MS = 3_000;
|
|
7
|
+
export class IdleDetector {
|
|
8
|
+
outputTail = '';
|
|
9
|
+
lastSpinnerAt = 0;
|
|
10
|
+
quiescenceTimer = null;
|
|
11
|
+
isIdle = false;
|
|
12
|
+
idleCallback = null;
|
|
13
|
+
completionPattern;
|
|
14
|
+
readyPattern;
|
|
15
|
+
readySeen = false;
|
|
16
|
+
constructor(cli) {
|
|
17
|
+
this.completionPattern = cli.completionPattern;
|
|
18
|
+
this.readyPattern = cli.readyPattern;
|
|
19
|
+
}
|
|
20
|
+
onIdle(cb) {
|
|
21
|
+
this.idleCallback = cb;
|
|
22
|
+
}
|
|
23
|
+
feed(data) {
|
|
24
|
+
if (this.isIdle)
|
|
25
|
+
return;
|
|
26
|
+
const stripped = this.stripAnsi(data);
|
|
27
|
+
this.outputTail = (this.outputTail + stripped).slice(-500);
|
|
28
|
+
// Track when the CLI's input prompt appears
|
|
29
|
+
if (this.readyPattern && !this.readySeen) {
|
|
30
|
+
if (this.readyPattern.test(this.outputTail)) {
|
|
31
|
+
this.readySeen = true;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Track spinner — but not if it's part of completion marker
|
|
35
|
+
if (SPINNER_RE.test(stripped) && !(this.completionPattern?.test(this.outputTail))) {
|
|
36
|
+
this.lastSpinnerAt = Date.now();
|
|
37
|
+
}
|
|
38
|
+
// Strategy 1: CLI-specific completion marker
|
|
39
|
+
if (this.completionPattern?.test(this.outputTail)) {
|
|
40
|
+
this.clearTimer();
|
|
41
|
+
this.quiescenceTimer = setTimeout(() => {
|
|
42
|
+
this.quiescenceTimer = null;
|
|
43
|
+
if (!this.isIdle)
|
|
44
|
+
this.markIdle();
|
|
45
|
+
}, 500);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
// Strategy 2: quiescence (PTY silence + no recent spinner)
|
|
49
|
+
// When readyPattern is set, suppress quiescence until the input prompt appears.
|
|
50
|
+
if (this.readyPattern && !this.readySeen)
|
|
51
|
+
return;
|
|
52
|
+
this.clearTimer();
|
|
53
|
+
this.quiescenceTimer = setTimeout(() => this.quiescenceCheck(), QUIESCENCE_MS);
|
|
54
|
+
}
|
|
55
|
+
reset() {
|
|
56
|
+
this.isIdle = false;
|
|
57
|
+
this.outputTail = '';
|
|
58
|
+
this.readySeen = false;
|
|
59
|
+
this.lastSpinnerAt = Date.now();
|
|
60
|
+
this.clearTimer();
|
|
61
|
+
}
|
|
62
|
+
dispose() {
|
|
63
|
+
this.clearTimer();
|
|
64
|
+
this.idleCallback = null;
|
|
65
|
+
}
|
|
66
|
+
quiescenceCheck() {
|
|
67
|
+
this.quiescenceTimer = null;
|
|
68
|
+
if (this.isIdle)
|
|
69
|
+
return;
|
|
70
|
+
const sinceSpinner = Date.now() - this.lastSpinnerAt;
|
|
71
|
+
if (sinceSpinner < SPINNER_GUARD_MS) {
|
|
72
|
+
this.quiescenceTimer = setTimeout(() => this.quiescenceCheck(), SPINNER_GUARD_MS - sinceSpinner + 200);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
this.markIdle();
|
|
76
|
+
}
|
|
77
|
+
markIdle() {
|
|
78
|
+
this.isIdle = true;
|
|
79
|
+
this.outputTail = '';
|
|
80
|
+
this.clearTimer();
|
|
81
|
+
this.idleCallback?.();
|
|
82
|
+
}
|
|
83
|
+
clearTimer() {
|
|
84
|
+
if (this.quiescenceTimer) {
|
|
85
|
+
clearTimeout(this.quiescenceTimer);
|
|
86
|
+
this.quiescenceTimer = null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
stripAnsi(str) {
|
|
90
|
+
return str
|
|
91
|
+
.replace(/\x1b\[(\d*)C/g, (_m, n) => ' '.repeat(Number(n) || 1))
|
|
92
|
+
.replace(/\x1b\[[0-9;]*[a-zA-Z]|\x1b\][^\x07]*\x07|\x1b[()][0-9A-B]|\x1b\[[\?]?[0-9;]*[hlmsuJ]/g, '');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=idle-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idle-detector.js","sourceRoot":"","sources":["../../src/utils/idle-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,MAAM;cACP,MAAM,WAAW,OAAO,EAAE,GAAG,IAAI;cAGjC,MAAM,WAAW,OAAO,EAAE,GAAG,IAAI;eAGhC,MAAM,WAAW,OAAO,EAAE,GAAG,IAAI;eAGjC,MAAM,WAAW,OAAO,EAAE,GAAG,IAAI;CAK7C,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
function timestamp() {
|
|
2
|
+
return new Date().toISOString();
|
|
3
|
+
}
|
|
4
|
+
// All log levels write to stderr. stdout is reserved for data protocols
|
|
5
|
+
// (e.g. MCP stdio transport) and must never be polluted with log text.
|
|
6
|
+
export const logger = {
|
|
7
|
+
info(msg, ...args) {
|
|
8
|
+
process.stderr.write(`[${timestamp()}] [INFO] ${msg} ${args.map(a => JSON.stringify(a)).join(' ')}\n`);
|
|
9
|
+
},
|
|
10
|
+
warn(msg, ...args) {
|
|
11
|
+
process.stderr.write(`[${timestamp()}] [WARN] ${msg} ${args.map(a => JSON.stringify(a)).join(' ')}\n`);
|
|
12
|
+
},
|
|
13
|
+
error(msg, ...args) {
|
|
14
|
+
process.stderr.write(`[${timestamp()}] [ERROR] ${msg} ${args.map(a => JSON.stringify(a)).join(' ')}\n`);
|
|
15
|
+
},
|
|
16
|
+
debug(msg, ...args) {
|
|
17
|
+
if (process.env.DEBUG) {
|
|
18
|
+
process.stderr.write(`[${timestamp()}] [DEBUG] ${msg} ${args.map(a => JSON.stringify(a)).join(' ')}\n`);
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,SAAS,SAAS;IAChB,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC;AAED,wEAAwE;AACxE,uEAAuE;AACvE,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,CAAC,GAAW,EAAE,GAAG,IAAe;QAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,SAAS,EAAE,YAAY,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACzG,CAAC;IACD,IAAI,CAAC,GAAW,EAAE,GAAG,IAAe;QAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,SAAS,EAAE,YAAY,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACzG,CAAC;IACD,KAAK,CAAC,GAAW,EAAE,GAAG,IAAe;QACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,SAAS,EAAE,aAAa,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1G,CAAC;IACD,KAAK,CAAC,GAAW,EAAE,GAAG,IAAe;QACnC,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,SAAS,EAAE,aAAa,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1G,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { LarkMessage } from '../types.js';
|
|
2
|
+
interface RawEventData {
|
|
3
|
+
sender: {
|
|
4
|
+
sender_id: {
|
|
5
|
+
open_id?: string;
|
|
6
|
+
user_id?: string;
|
|
7
|
+
union_id?: string;
|
|
8
|
+
};
|
|
9
|
+
sender_type: string;
|
|
10
|
+
tenant_key?: string;
|
|
11
|
+
};
|
|
12
|
+
message: {
|
|
13
|
+
message_id: string;
|
|
14
|
+
root_id?: string;
|
|
15
|
+
parent_id?: string;
|
|
16
|
+
message_type: string;
|
|
17
|
+
content: string;
|
|
18
|
+
chat_id: string;
|
|
19
|
+
chat_type: string;
|
|
20
|
+
create_time: string;
|
|
21
|
+
mentions?: Array<{
|
|
22
|
+
key: string;
|
|
23
|
+
name: string;
|
|
24
|
+
id?: {
|
|
25
|
+
open_id?: string;
|
|
26
|
+
user_id?: string;
|
|
27
|
+
union_id?: string;
|
|
28
|
+
};
|
|
29
|
+
tenant_key?: string;
|
|
30
|
+
}>;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export interface MessageResource {
|
|
34
|
+
type: 'image' | 'file';
|
|
35
|
+
key: string;
|
|
36
|
+
name: string;
|
|
37
|
+
}
|
|
38
|
+
export declare function extractResources(msgType: string, rawContent: string): MessageResource[];
|
|
39
|
+
export declare function parseEventMessage(data: RawEventData): {
|
|
40
|
+
parsed: LarkMessage;
|
|
41
|
+
resources: MessageResource[];
|
|
42
|
+
};
|
|
43
|
+
export declare function parseApiMessage(msg: any): LarkMessage;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=message-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-parser.d.ts","sourceRoot":"","sources":["../../src/utils/message-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK/C,UAAU,YAAY;IACpB,MAAM,EAAE;QACN,SAAS,EAAE;YACT,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC;QACF,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,KAAK,CAAC;YACf,GAAG,EAAE,MAAM,CAAC;YACZ,IAAI,EAAE,MAAM,CAAC;YACb,EAAE,CAAC,EAAE;gBAAE,OAAO,CAAC,EAAE,MAAM,CAAC;gBAAC,OAAO,CAAC,EAAE,MAAM,CAAC;gBAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC;YAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;SACrB,CAAC,CAAC;KACJ,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,eAAe,EAAE,CAmCvF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,eAAe,EAAE,CAAA;CAAE,CAmB3G;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,GAAG,GAAG,WAAW,CAUrD"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { logger } from './logger.js';
|
|
2
|
+
export function extractResources(msgType, rawContent) {
|
|
3
|
+
try {
|
|
4
|
+
const parsed = JSON.parse(rawContent);
|
|
5
|
+
if (msgType === 'image') {
|
|
6
|
+
const imageKey = parsed.image_key;
|
|
7
|
+
if (imageKey) {
|
|
8
|
+
return [{ type: 'image', key: imageKey, name: `${imageKey}.jpg` }];
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
if (msgType === 'file') {
|
|
12
|
+
const fileKey = parsed.file_key;
|
|
13
|
+
if (fileKey) {
|
|
14
|
+
return [{ type: 'file', key: fileKey, name: parsed.file_name ?? fileKey }];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (msgType === 'post') {
|
|
18
|
+
const resources = [];
|
|
19
|
+
const { content: contentBlocks } = resolvePostBody(parsed);
|
|
20
|
+
for (const block of contentBlocks) {
|
|
21
|
+
const nodes = Array.isArray(block) ? block : [block];
|
|
22
|
+
for (const node of nodes) {
|
|
23
|
+
if (node.tag === 'img' && node.image_key) {
|
|
24
|
+
resources.push({ type: 'image', key: node.image_key, name: `${node.image_key}.jpg` });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return resources;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// ignore parse errors
|
|
33
|
+
}
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
export function parseEventMessage(data) {
|
|
37
|
+
const { sender, message } = data;
|
|
38
|
+
// Debug: log raw message for non-text types
|
|
39
|
+
if (message.message_type !== 'text') {
|
|
40
|
+
logger.info(`[parser] type=${message.message_type} content=${message.content} keys=${Object.keys(message).join(',')}`);
|
|
41
|
+
}
|
|
42
|
+
const resources = extractResources(message.message_type, message.content);
|
|
43
|
+
const parsed = {
|
|
44
|
+
messageId: message.message_id,
|
|
45
|
+
rootId: message.root_id ?? '',
|
|
46
|
+
senderId: sender.sender_id?.open_id ?? '',
|
|
47
|
+
senderType: sender.sender_type,
|
|
48
|
+
msgType: message.message_type,
|
|
49
|
+
content: extractTextContent(message.message_type, message.content, message.mentions),
|
|
50
|
+
createTime: message.create_time,
|
|
51
|
+
};
|
|
52
|
+
return { parsed, resources };
|
|
53
|
+
}
|
|
54
|
+
export function parseApiMessage(msg) {
|
|
55
|
+
return {
|
|
56
|
+
messageId: msg.message_id ?? '',
|
|
57
|
+
rootId: msg.root_id ?? msg.thread_id ?? '',
|
|
58
|
+
senderId: msg.sender?.id ?? '',
|
|
59
|
+
senderType: msg.sender?.sender_type ?? 'unknown',
|
|
60
|
+
msgType: msg.msg_type ?? 'text',
|
|
61
|
+
content: extractTextContent(msg.msg_type ?? 'text', msg.body?.content ?? ''),
|
|
62
|
+
createTime: msg.create_time ?? '',
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** Resolve post body from either wrapped {"zh_cn":{title,content}} or unwrapped {title,content} format */
|
|
66
|
+
function resolvePostBody(parsed) {
|
|
67
|
+
// Unwrapped: has content array directly
|
|
68
|
+
if (Array.isArray(parsed.content)) {
|
|
69
|
+
return { title: parsed.title ?? '', content: parsed.content };
|
|
70
|
+
}
|
|
71
|
+
// Wrapped in language key: {"zh_cn": {title, content}}
|
|
72
|
+
for (const key of Object.keys(parsed)) {
|
|
73
|
+
const val = parsed[key];
|
|
74
|
+
if (val && typeof val === 'object' && Array.isArray(val.content)) {
|
|
75
|
+
return { title: val.title ?? '', content: val.content };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return { title: '', content: [] };
|
|
79
|
+
}
|
|
80
|
+
function resolveMentions(text, mentions) {
|
|
81
|
+
if (!mentions || mentions.length === 0) {
|
|
82
|
+
// No mention info available — strip placeholders
|
|
83
|
+
return text.replace(/@_user_\d+/g, '').replace(/\s{2,}/g, ' ').trim();
|
|
84
|
+
}
|
|
85
|
+
let result = text;
|
|
86
|
+
for (const m of mentions) {
|
|
87
|
+
result = result.replace(m.key, `@${m.name}`);
|
|
88
|
+
}
|
|
89
|
+
return result.trim();
|
|
90
|
+
}
|
|
91
|
+
function extractTextContent(msgType, rawContent, mentions) {
|
|
92
|
+
try {
|
|
93
|
+
if (msgType === 'text') {
|
|
94
|
+
const parsed = JSON.parse(rawContent);
|
|
95
|
+
return resolveMentions(parsed.text ?? rawContent, mentions);
|
|
96
|
+
}
|
|
97
|
+
if (msgType === 'post') {
|
|
98
|
+
const parsed = JSON.parse(rawContent);
|
|
99
|
+
const { title, content } = resolvePostBody(parsed);
|
|
100
|
+
const body = content
|
|
101
|
+
.flat()
|
|
102
|
+
.filter((node) => node.tag === 'text' || node.tag === 'a' || node.tag === 'at')
|
|
103
|
+
.map((node) => {
|
|
104
|
+
if (node.tag === 'at')
|
|
105
|
+
return `@${node.user_name ?? 'unknown'}`;
|
|
106
|
+
return node.text ?? node.href ?? '';
|
|
107
|
+
})
|
|
108
|
+
.join('');
|
|
109
|
+
return title ? `${title}\n${body}` : body;
|
|
110
|
+
}
|
|
111
|
+
if (msgType === 'image') {
|
|
112
|
+
return '[图片]';
|
|
113
|
+
}
|
|
114
|
+
if (msgType === 'file') {
|
|
115
|
+
try {
|
|
116
|
+
const p = JSON.parse(rawContent);
|
|
117
|
+
return `[文件: ${p.file_name ?? 'unknown'}]`;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return '[文件]';
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (msgType === 'interactive') {
|
|
124
|
+
return '[interactive card]';
|
|
125
|
+
}
|
|
126
|
+
return rawContent;
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return rawContent;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=message-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-parser.js","sourceRoot":"","sources":["../../src/utils/message-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare class TerminalRenderer {
|
|
2
|
+
private terminal;
|
|
3
|
+
private lastHash;
|
|
4
|
+
/** Absolute line index where the current turn starts. */
|
|
5
|
+
private turnBaselineY;
|
|
6
|
+
/** Best content seen this turn — prevents TUI redraws from wiping output. */
|
|
7
|
+
private peakContent;
|
|
8
|
+
constructor(cols: number, rows: number);
|
|
9
|
+
/** Feed raw PTY data into the virtual terminal. */
|
|
10
|
+
write(data: string): void;
|
|
11
|
+
/**
|
|
12
|
+
* Mark the start of a new conversation turn.
|
|
13
|
+
* Subsequent snapshots will only include content from after this point.
|
|
14
|
+
*/
|
|
15
|
+
markNewTurn(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Snapshot the current screen content.
|
|
18
|
+
*
|
|
19
|
+
* Strategy:
|
|
20
|
+
* 1. Try from turn baseline with Phase 1 marker gating (Claude Code style).
|
|
21
|
+
* 2. If empty, fall back to full viewport without Phase 1 (CoCo/TUI style).
|
|
22
|
+
* TUI apps redraw the entire screen, so content may appear anywhere.
|
|
23
|
+
* 3. Peak retention: save the best content seen this turn. When the TUI
|
|
24
|
+
* redraws to idle (empty screen), return the saved peak instead.
|
|
25
|
+
*/
|
|
26
|
+
snapshot(): {
|
|
27
|
+
content: string;
|
|
28
|
+
changed: boolean;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Read and filter terminal content starting from `startY`.
|
|
32
|
+
* @param skipPhase1 When true, include all non-chrome lines (no marker gating).
|
|
33
|
+
* Used for TUI viewport fallback where output markers differ.
|
|
34
|
+
*/
|
|
35
|
+
private extractContent;
|
|
36
|
+
resize(cols: number, rows: number): void;
|
|
37
|
+
dispose(): void;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=terminal-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-renderer.d.ts","sourceRoot":"","sources":["../../src/utils/terminal-renderer.ts"],"names":[],"mappings":"AAmFA,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,QAAQ,CAAM;IACtB,yDAAyD;IACzD,OAAO,CAAC,aAAa,CAAK;IAC1B,6EAA6E;IAC7E,OAAO,CAAC,WAAW,CAAM;gBAEb,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAItC,mDAAmD;IACnD,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIzB;;;OAGG;IACH,WAAW,IAAI,IAAI;IAoBnB;;;;;;;;;OASG;IACH,QAAQ,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;IA4BjD;;;;OAIG;IACH,OAAO,CAAC,cAAc;IA2CtB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxC,OAAO,IAAI,IAAI;CAGhB"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Headless terminal renderer: feeds PTY data into an xterm-headless instance
|
|
3
|
+
* and periodically snapshots the rendered screen for Feishu card updates.
|
|
4
|
+
*
|
|
5
|
+
* Filters out TUI chrome and preamble (logo, version, prompt echo, system
|
|
6
|
+
* instructions) so only the CLI's actual work output appears in the card.
|
|
7
|
+
*
|
|
8
|
+
* Supports two rendering styles:
|
|
9
|
+
* - CLI-style (Claude Code, Aiden): output appends to scrollback. Baseline
|
|
10
|
+
* tracking isolates current-turn content. Phase 1 (OUTPUT_MARKER_RE) gates
|
|
11
|
+
* content detection.
|
|
12
|
+
* - TUI-style (CoCo, Codex): cursor-positioned full-screen UI. Content can
|
|
13
|
+
* be overwritten when the TUI redraws (e.g. response → idle prompt).
|
|
14
|
+
* Viewport fallback + peak retention ensure response content is captured.
|
|
15
|
+
*
|
|
16
|
+
* Timer overlay avoidance: The PTY is intentionally wider than normal so that
|
|
17
|
+
* right-aligned TUI overlays (elapsed time, timeout counters) are rendered
|
|
18
|
+
* far to the right. Snapshots only read the first `contentCols` columns,
|
|
19
|
+
* cleanly excluding the overlay area — no fragile regex stripping needed.
|
|
20
|
+
*/
|
|
21
|
+
import xtermHeadless from '@xterm/headless';
|
|
22
|
+
const { Terminal } = xtermHeadless;
|
|
23
|
+
import { createHash } from 'node:crypto';
|
|
24
|
+
// ─── Box-Drawing Cleanup ─────────────────────────────────────────────────────
|
|
25
|
+
// Claude Code TUI renders panel borders with box-drawing characters.
|
|
26
|
+
// The headless terminal captures them overlapping with content text.
|
|
27
|
+
/** Strip box-drawing horizontal/vertical/corner characters, collapse spaces. */
|
|
28
|
+
function cleanBoxDrawing(line) {
|
|
29
|
+
return line
|
|
30
|
+
.replace(/[─━│┌┐└┘├┤┬┴┼╭╮╯╰]/g, ' ')
|
|
31
|
+
.replace(/ +/g, ' ')
|
|
32
|
+
.trimEnd();
|
|
33
|
+
}
|
|
34
|
+
// ─── Line Filters ────────────────────────────────────────────────────────────
|
|
35
|
+
/** Bare prompt line: ❯ (Claude) or > (Aiden) with optional trailing whitespace */
|
|
36
|
+
const BARE_PROMPT_RE = /^[❯>]\s*$/;
|
|
37
|
+
/** Input echo: ❯ or > followed by user text */
|
|
38
|
+
const INPUT_ECHO_RE = /^[❯>]\s+\S/;
|
|
39
|
+
/** Status bar: Claude ("bypass permissions", "⏵⏵", "/model"), Aiden ("agent full mode"),
|
|
40
|
+
* CoCo ("accept all tools", "shell mode") */
|
|
41
|
+
const STATUS_BAR_RE = /bypass permissions|⏵⏵|shift\+tab|\/model|auto-update|agent full mode|IDE: \w+|accept all tools/;
|
|
42
|
+
/** CLI logo — block drawing characters used in ASCII art splash screens.
|
|
43
|
+
* Includes Claude Code (▐▛█▜▝▘) and CoCo (▄▀◆) character sets. */
|
|
44
|
+
const LOGO_RE = /[▐▛█▜▝▘▄▀◆]{2,}/;
|
|
45
|
+
/** CLI version / banner info lines */
|
|
46
|
+
const VERSION_RE = /Claude Code v\d|^\s*(Opus|Sonnet|Haiku)\s+\d|>_ Aiden \(v[\d.]+\)|Trae CLI \d|Formerly Coco/;
|
|
47
|
+
/** CoCo TUI chrome: input placeholder, mode/keyboard hints, welcome screen */
|
|
48
|
+
const COCO_CHROME_RE = /Ask anything|shell mode.*command mode|Ctrl\+J new line|Codebase Copilot|Did you know|Welcome back,|Use \/status|Announcements|code\.byted\.org/;
|
|
49
|
+
/** Empty or whitespace-only */
|
|
50
|
+
const BLANK_RE = /^\s*$/;
|
|
51
|
+
function shouldSkipLine(line) {
|
|
52
|
+
return (BARE_PROMPT_RE.test(line) ||
|
|
53
|
+
INPUT_ECHO_RE.test(line) ||
|
|
54
|
+
STATUS_BAR_RE.test(line) ||
|
|
55
|
+
LOGO_RE.test(line) ||
|
|
56
|
+
VERSION_RE.test(line) ||
|
|
57
|
+
COCO_CHROME_RE.test(line));
|
|
58
|
+
}
|
|
59
|
+
/** CLI output markers — lines starting with these indicate real work output.
|
|
60
|
+
* Includes CoCo spinner chars (❇❋✢) alongside Claude Code's markers. */
|
|
61
|
+
const OUTPUT_MARKER_RE = /^[●·⎿✓⚠★☐☑⏵✽✻❇❋✢]|^\s+⎿/;
|
|
62
|
+
/**
|
|
63
|
+
* How many columns to read from each line for the Feishu card snapshot.
|
|
64
|
+
* Content beyond this is ignored — this is where TUI overlays (timer, timeout)
|
|
65
|
+
* live when the PTY is wider than this value.
|
|
66
|
+
*/
|
|
67
|
+
const SNAPSHOT_COLS = 160;
|
|
68
|
+
export class TerminalRenderer {
|
|
69
|
+
terminal;
|
|
70
|
+
lastHash = '';
|
|
71
|
+
/** Absolute line index where the current turn starts. */
|
|
72
|
+
turnBaselineY = 0;
|
|
73
|
+
/** Best content seen this turn — prevents TUI redraws from wiping output. */
|
|
74
|
+
peakContent = '';
|
|
75
|
+
constructor(cols, rows) {
|
|
76
|
+
this.terminal = new Terminal({ cols, rows, allowProposedApi: true });
|
|
77
|
+
}
|
|
78
|
+
/** Feed raw PTY data into the virtual terminal. */
|
|
79
|
+
write(data) {
|
|
80
|
+
this.terminal.write(data);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Mark the start of a new conversation turn.
|
|
84
|
+
* Subsequent snapshots will only include content from after this point.
|
|
85
|
+
*/
|
|
86
|
+
markNewTurn() {
|
|
87
|
+
const buffer = this.terminal.buffer.active;
|
|
88
|
+
const baseY = buffer.baseY;
|
|
89
|
+
const rows = this.terminal.rows;
|
|
90
|
+
// Find the last non-empty line in the current viewport
|
|
91
|
+
let lastContentY = baseY;
|
|
92
|
+
for (let y = rows - 1; y >= 0; y--) {
|
|
93
|
+
const line = buffer.getLine(baseY + y);
|
|
94
|
+
if (line && line.translateToString(true).trimEnd()) {
|
|
95
|
+
lastContentY = baseY + y + 1;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
this.turnBaselineY = lastContentY;
|
|
100
|
+
this.peakContent = '';
|
|
101
|
+
this.lastHash = '';
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Snapshot the current screen content.
|
|
105
|
+
*
|
|
106
|
+
* Strategy:
|
|
107
|
+
* 1. Try from turn baseline with Phase 1 marker gating (Claude Code style).
|
|
108
|
+
* 2. If empty, fall back to full viewport without Phase 1 (CoCo/TUI style).
|
|
109
|
+
* TUI apps redraw the entire screen, so content may appear anywhere.
|
|
110
|
+
* 3. Peak retention: save the best content seen this turn. When the TUI
|
|
111
|
+
* redraws to idle (empty screen), return the saved peak instead.
|
|
112
|
+
*/
|
|
113
|
+
snapshot() {
|
|
114
|
+
const buffer = this.terminal.buffer.active;
|
|
115
|
+
const baseY = buffer.baseY;
|
|
116
|
+
// Strategy 1: baseline read with Phase 1 marker gating (CLI-style output)
|
|
117
|
+
let content = this.extractContent(this.turnBaselineY, false);
|
|
118
|
+
// Strategy 2: full viewport without Phase 1 (TUI-style — content anywhere on screen)
|
|
119
|
+
if (!content) {
|
|
120
|
+
content = this.extractContent(baseY, true);
|
|
121
|
+
}
|
|
122
|
+
// Peak retention — TUI redraws can wipe response from the terminal buffer.
|
|
123
|
+
// Save non-empty content; return saved peak when current screen is empty.
|
|
124
|
+
if (content) {
|
|
125
|
+
this.peakContent = content;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
content = this.peakContent;
|
|
129
|
+
}
|
|
130
|
+
// Hash-based change detection
|
|
131
|
+
const hash = createHash('md5').update(content).digest('hex');
|
|
132
|
+
const changed = hash !== this.lastHash;
|
|
133
|
+
this.lastHash = hash;
|
|
134
|
+
return { content, changed };
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Read and filter terminal content starting from `startY`.
|
|
138
|
+
* @param skipPhase1 When true, include all non-chrome lines (no marker gating).
|
|
139
|
+
* Used for TUI viewport fallback where output markers differ.
|
|
140
|
+
*/
|
|
141
|
+
extractContent(startY, skipPhase1) {
|
|
142
|
+
const buffer = this.terminal.buffer.active;
|
|
143
|
+
const baseY = buffer.baseY;
|
|
144
|
+
const rows = this.terminal.rows;
|
|
145
|
+
const readCols = Math.min(SNAPSHOT_COLS, this.terminal.cols);
|
|
146
|
+
const endY = baseY + rows;
|
|
147
|
+
const rawLines = [];
|
|
148
|
+
for (let y = startY; y < endY; y++) {
|
|
149
|
+
const line = buffer.getLine(y);
|
|
150
|
+
if (!line)
|
|
151
|
+
continue;
|
|
152
|
+
rawLines.push(cleanBoxDrawing(line.translateToString(true, 0, readCols)));
|
|
153
|
+
}
|
|
154
|
+
let foundOutput = skipPhase1;
|
|
155
|
+
const filtered = [];
|
|
156
|
+
for (const line of rawLines) {
|
|
157
|
+
if (!foundOutput) {
|
|
158
|
+
// Phase 1: skip lines until we see an output marker
|
|
159
|
+
if (OUTPUT_MARKER_RE.test(line)) {
|
|
160
|
+
foundOutput = true;
|
|
161
|
+
filtered.push(line);
|
|
162
|
+
}
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
// Phase 2: filter TUI chrome but keep content
|
|
166
|
+
if (shouldSkipLine(line))
|
|
167
|
+
continue;
|
|
168
|
+
filtered.push(line);
|
|
169
|
+
}
|
|
170
|
+
// Trim leading and trailing empty lines
|
|
171
|
+
while (filtered.length > 0 && BLANK_RE.test(filtered[0])) {
|
|
172
|
+
filtered.shift();
|
|
173
|
+
}
|
|
174
|
+
while (filtered.length > 0 && BLANK_RE.test(filtered[filtered.length - 1])) {
|
|
175
|
+
filtered.pop();
|
|
176
|
+
}
|
|
177
|
+
return filtered.join('\n');
|
|
178
|
+
}
|
|
179
|
+
resize(cols, rows) {
|
|
180
|
+
this.terminal.resize(cols, rows);
|
|
181
|
+
}
|
|
182
|
+
dispose() {
|
|
183
|
+
this.terminal.dispose();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=terminal-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-renderer.js","sourceRoot":"","sources":["../../src/utils/terminal-renderer.ts"],"names":[],"mappings":"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"}
|
package/dist/worker.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":""}
|