talon-agent 4.3.2 → 4.4.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/package.json +1 -1
- package/src/app.ts +1 -1
- package/src/backend/claude-sdk/doctor.ts +1 -1
- package/src/backend/claude-sdk/state.ts +1 -1
- package/src/backend/codex/doctor.ts +1 -1
- package/src/backend/codex/init.ts +1 -1
- package/src/backend/codex/state.ts +1 -1
- package/src/backend/openai-agents/doctor.ts +1 -1
- package/src/backend/openai-agents/init.ts +1 -1
- package/src/backend/openai-agents/state.ts +1 -1
- package/src/backend/remote-server/factory.ts +1 -1
- package/src/backend/remote-server/mcp.ts +1 -1
- package/src/backend/remote-server/server-bindings.ts +1 -1
- package/src/backend/remote-server/state.ts +1 -1
- package/src/backend/shared/system-prompt.ts +1 -1
- package/src/bootstrap.ts +3 -3
- package/src/cli/chat.ts +1 -1
- package/src/cli/config.ts +2 -2
- package/src/cli/doctor.ts +1 -1
- package/src/cli/index.ts +8 -0
- package/src/cli/memory.ts +166 -0
- package/src/cli/setup.ts +1 -1
- package/src/core/agent-runtime/backend-registry.ts +2 -2
- package/src/core/agent-runtime/model-ref.ts +2 -2
- package/src/core/auth/expiry-monitor.ts +1 -1
- package/src/{util/config.ts → core/config/index.ts} +8 -8
- package/src/core/{doctor.ts → doctor/index.ts} +11 -11
- package/src/core/engine/backend-controller/legacy.ts +1 -1
- package/src/core/engine/backend-controller/pool.ts +1 -1
- package/src/core/engine/backend-controller/rebind.ts +1 -1
- package/src/core/engine/backend-controller/state.ts +1 -1
- package/src/core/engine/gateway-actions/plugins.ts +1 -1
- package/src/core/engine/model-audit.ts +1 -1
- package/src/core/{notify.ts → frontend-runtime/admin-notify.ts} +1 -1
- package/src/core/frontend-runtime/capabilities.ts +1 -1
- package/src/core/models/active-model.ts +1 -1
- package/src/core/plugin/builtins.ts +2 -2
- package/src/core/plugin/manage.ts +1 -1
- package/src/core/plugin/native-runtimes.ts +1 -1
- package/src/frontend/discord/admin.ts +1 -1
- package/src/frontend/discord/callbacks/components/index.ts +1 -1
- package/src/frontend/discord/callbacks/components/settings.ts +1 -1
- package/src/frontend/discord/callbacks/components/types.ts +1 -1
- package/src/frontend/discord/callbacks/modals.ts +1 -1
- package/src/frontend/discord/commands/admin.ts +2 -2
- package/src/frontend/discord/commands/definitions.ts +1 -1
- package/src/frontend/discord/commands/info.ts +1 -1
- package/src/frontend/discord/commands/router.ts +1 -1
- package/src/frontend/discord/commands/session.ts +1 -1
- package/src/frontend/discord/commands/settings.ts +1 -1
- package/src/frontend/discord/handlers/delivery.ts +1 -1
- package/src/frontend/discord/handlers/messages.ts +1 -1
- package/src/frontend/discord/handlers/queue.ts +1 -1
- package/src/frontend/discord/handlers/state.ts +1 -1
- package/src/frontend/discord/index.ts +1 -1
- package/src/frontend/discord/middleware.ts +1 -1
- package/src/frontend/discord/render.ts +1 -1
- package/src/frontend/discord/runtime.ts +1 -1
- package/src/frontend/native/extensions.ts +4 -1
- package/src/frontend/native/index.ts +1 -1
- package/src/frontend/native/runtime.ts +1 -1
- package/src/frontend/native/settings.ts +1 -1
- package/src/frontend/shared/model-commands.ts +1 -1
- package/src/frontend/shared/plan-usage-report.ts +1 -1
- package/src/frontend/shared/reasoning-levels.ts +1 -1
- package/src/frontend/shared/session-status.ts +1 -1
- package/src/frontend/teams/index.ts +1 -1
- package/src/frontend/teams/runtime.ts +1 -1
- package/src/frontend/telegram/actions/chat-info.ts +1 -1
- package/src/frontend/telegram/actions/coerce.ts +15 -0
- package/src/frontend/telegram/actions/index.ts +2 -2
- package/src/frontend/telegram/actions/media.ts +1 -1
- package/src/frontend/telegram/actions/messaging.ts +3 -4
- package/src/frontend/telegram/actions/moderation/chat.ts +63 -0
- package/src/frontend/telegram/actions/moderation/index.ts +74 -0
- package/src/frontend/telegram/actions/moderation/members.ts +77 -0
- package/src/frontend/telegram/actions/moderation/permissions.ts +69 -0
- package/src/frontend/telegram/actions/moderation/topics.ts +48 -0
- package/src/frontend/telegram/actions/moderation/types.ts +16 -0
- package/src/frontend/telegram/actions/rich-messages.ts +51 -0
- package/src/frontend/telegram/actions/{shared.ts → send.ts} +9 -59
- package/src/frontend/telegram/admin/background.ts +66 -0
- package/src/frontend/telegram/admin/chunked-reply.ts +20 -0
- package/src/frontend/telegram/admin/health.ts +81 -0
- package/src/frontend/telegram/admin/sessions.ts +105 -0
- package/src/frontend/telegram/admin.ts +57 -262
- package/src/frontend/telegram/callbacks/auth.ts +1 -1
- package/src/frontend/telegram/callbacks/effort.ts +1 -1
- package/src/frontend/telegram/callbacks/index.ts +3 -3
- package/src/frontend/telegram/callbacks/metrics.ts +1 -1
- package/src/frontend/telegram/callbacks/model/backend.ts +156 -0
- package/src/frontend/telegram/callbacks/model/control.ts +29 -0
- package/src/frontend/telegram/callbacks/model/nav.ts +54 -0
- package/src/frontend/telegram/callbacks/model/select.ts +100 -0
- package/src/frontend/telegram/callbacks/model/types.ts +39 -0
- package/src/frontend/telegram/callbacks/model/views.ts +116 -0
- package/src/frontend/telegram/callbacks/model.ts +61 -331
- package/src/frontend/telegram/callbacks/pulse.ts +1 -1
- package/src/frontend/telegram/callbacks/{shared.ts → query.ts} +3 -2
- package/src/frontend/telegram/callbacks/settings.ts +1 -1
- package/src/frontend/telegram/callbacks/whatsapp.ts +1 -1
- package/src/frontend/telegram/commands/admin.ts +108 -77
- package/src/frontend/telegram/commands/index.ts +1 -1
- package/src/frontend/telegram/commands/settings.ts +65 -43
- package/src/frontend/telegram/commands/state.ts +1 -1
- package/src/frontend/telegram/commands/whatsapp-pairing.ts +1 -1
- package/src/frontend/telegram/handlers/context.ts +1 -1
- package/src/frontend/telegram/handlers/delivery.ts +2 -2
- package/src/frontend/telegram/handlers/messages.ts +1 -1
- package/src/frontend/telegram/handlers/queue.ts +1 -1
- package/src/frontend/telegram/handlers/state.ts +1 -1
- package/src/frontend/telegram/helpers/diagnostics.ts +1 -1
- package/src/frontend/telegram/index.ts +1 -1
- package/src/frontend/telegram/middleware.ts +167 -202
- package/src/frontend/telegram/model-menu.ts +1 -1
- package/src/frontend/terminal/builtins/context.ts +184 -0
- package/src/frontend/terminal/builtins/help.ts +35 -0
- package/src/frontend/terminal/builtins/index.ts +23 -0
- package/src/frontend/terminal/builtins/model.ts +198 -0
- package/src/frontend/terminal/builtins/session.ts +101 -0
- package/src/frontend/terminal/builtins/status.ts +202 -0
- package/src/frontend/terminal/command-registry.ts +80 -0
- package/src/frontend/terminal/commands.ts +11 -674
- package/src/frontend/terminal/index.ts +1 -1
- package/src/frontend/terminal/input/history.ts +64 -0
- package/src/frontend/terminal/input/keys.ts +143 -0
- package/src/frontend/terminal/input/parts.ts +33 -0
- package/src/frontend/terminal/input/paste.ts +53 -0
- package/src/frontend/terminal/input/render.ts +42 -0
- package/src/frontend/terminal/input/state.ts +60 -0
- package/src/frontend/terminal/input.ts +27 -342
- package/src/frontend/whatsapp/connection.ts +1 -1
- package/src/frontend/whatsapp/index.ts +2 -2
- package/src/frontend/whatsapp/pairing-service.ts +1 -1
- package/src/frontend/whatsapp/runtime.ts +1 -1
- package/src/plugins/github/provision.ts +1 -1
- package/src/plugins/mempalace/provision.ts +1 -1
- package/src/plugins/playwright/provision.ts +1 -1
- package/src/storage/memory.ts +505 -0
- package/src/storage/repositories/memory-repo.ts +308 -0
- package/src/storage/sql/memory.sql +95 -0
- package/src/storage/sql/schema.sql +81 -0
- package/src/storage/sql/statements.generated.ts +146 -0
- package/src/frontend/telegram/actions/moderation.ts +0 -255
- /package/src/core/{doctor-types.ts → doctor/types.ts} +0 -0
- /package/src/core/{pairing-broker.ts → frontend-runtime/pairing-broker.ts} +0 -0
|
@@ -4,9 +4,18 @@
|
|
|
4
4
|
* Input is a list of parts: text segments and collapsed paste blocks.
|
|
5
5
|
* You can type, paste, type more, paste again. Backspace removes from the end.
|
|
6
6
|
* Enter submits everything. Ctrl+U clears all. Up/Down walk prompt history.
|
|
7
|
+
*
|
|
8
|
+
* State lives in `input/state.ts`; paste, keys and drawing are each their own
|
|
9
|
+
* module under `input/`. This file is the wiring.
|
|
7
10
|
*/
|
|
8
11
|
|
|
9
|
-
import
|
|
12
|
+
import { createInputState } from "./input/state.js";
|
|
13
|
+
import { consumePasteChunk } from "./input/paste.js";
|
|
14
|
+
import { handleKeyChunk } from "./input/keys.js";
|
|
15
|
+
import { redraw } from "./input/render.js";
|
|
16
|
+
|
|
17
|
+
export type { InputPart } from "./input/parts.js";
|
|
18
|
+
export { PromptHistory } from "./input/history.js";
|
|
10
19
|
|
|
11
20
|
// ── Types ────────────────────────────────────────────────────────────────────
|
|
12
21
|
|
|
@@ -19,232 +28,10 @@ export type InputHandler = {
|
|
|
19
28
|
resume(): void;
|
|
20
29
|
};
|
|
21
30
|
|
|
22
|
-
export type InputPart =
|
|
23
|
-
{ type: "text"; content: string } | { type: "paste"; content: string };
|
|
24
|
-
type TextPart = Extract<InputPart, { type: "text" }>;
|
|
25
|
-
type PastePart = Extract<InputPart, { type: "paste" }>;
|
|
26
|
-
|
|
27
|
-
// ── Constants ────────────────────────────────────────────────────────────────
|
|
28
|
-
|
|
29
|
-
const PASTE_COLLAPSE_LINES = 3;
|
|
30
|
-
const PASTE_COLLAPSE_CHARS = 150;
|
|
31
|
-
const PASTE_START = "\x1b[200~";
|
|
32
|
-
const PASTE_END = "\x1b[201~";
|
|
33
|
-
const MAX_HISTORY_ITEMS = 100;
|
|
34
|
-
|
|
35
|
-
function cloneParts(parts: readonly InputPart[]): InputPart[] {
|
|
36
|
-
return parts.map((part) => ({ ...part }));
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function partsText(parts: readonly InputPart[]): string {
|
|
40
|
-
return parts
|
|
41
|
-
.map((part) => part.content)
|
|
42
|
-
.join("\n")
|
|
43
|
-
.trim();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* In-process prompt history. Keeping this out of the persistent stores avoids
|
|
48
|
-
* creating a second plaintext transcript while still giving terminal users
|
|
49
|
-
* the expected Up/Down workflow.
|
|
50
|
-
*/
|
|
51
|
-
export class PromptHistory {
|
|
52
|
-
private readonly entries: InputPart[][] = [];
|
|
53
|
-
private cursor = 0;
|
|
54
|
-
private draft: InputPart[] | null = null;
|
|
55
|
-
|
|
56
|
-
constructor(private readonly maxItems = MAX_HISTORY_ITEMS) {}
|
|
57
|
-
|
|
58
|
-
add(parts: readonly InputPart[]): void {
|
|
59
|
-
const text = partsText(parts);
|
|
60
|
-
if (!text) return;
|
|
61
|
-
|
|
62
|
-
const latest = this.entries.at(-1);
|
|
63
|
-
if (!latest || partsText(latest) !== text) {
|
|
64
|
-
this.entries.push(cloneParts(parts));
|
|
65
|
-
if (this.entries.length > this.maxItems) this.entries.shift();
|
|
66
|
-
}
|
|
67
|
-
this.resetNavigation();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
move(
|
|
71
|
-
direction: "previous" | "next",
|
|
72
|
-
current: readonly InputPart[],
|
|
73
|
-
): InputPart[] | undefined {
|
|
74
|
-
if (this.entries.length === 0) return undefined;
|
|
75
|
-
|
|
76
|
-
if (direction === "previous") {
|
|
77
|
-
if (this.cursor === this.entries.length) {
|
|
78
|
-
this.draft = cloneParts(current);
|
|
79
|
-
}
|
|
80
|
-
if (this.cursor > 0) this.cursor--;
|
|
81
|
-
return cloneParts(this.entries[this.cursor]!);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (this.cursor === this.entries.length) return undefined;
|
|
85
|
-
if (this.cursor < this.entries.length - 1) {
|
|
86
|
-
this.cursor++;
|
|
87
|
-
return cloneParts(this.entries[this.cursor]!);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
this.cursor = this.entries.length;
|
|
91
|
-
return cloneParts(this.draft ?? [{ type: "text", content: "" }]);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/** Preserve an edited recalled prompt as the current draft. */
|
|
95
|
-
detach(parts: readonly InputPart[]): void {
|
|
96
|
-
if (this.cursor === this.entries.length) return;
|
|
97
|
-
this.cursor = this.entries.length;
|
|
98
|
-
this.draft = cloneParts(parts);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
resetNavigation(): void {
|
|
102
|
-
this.cursor = this.entries.length;
|
|
103
|
-
this.draft = null;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
31
|
// ── Factory ──────────────────────────────────────────────────────────────────
|
|
108
32
|
|
|
109
33
|
export function createInput(promptStr: string): InputHandler {
|
|
110
|
-
|
|
111
|
-
let pendingResolve: ((value: string) => void) | null = null;
|
|
112
|
-
let paused = false;
|
|
113
|
-
|
|
114
|
-
// Input is an ordered list of parts
|
|
115
|
-
let parts: InputPart[] = [{ type: "text", content: "" }];
|
|
116
|
-
const history = new PromptHistory();
|
|
117
|
-
|
|
118
|
-
// Bracketed paste accumulation
|
|
119
|
-
let inPaste = false;
|
|
120
|
-
let pasteAccum = "";
|
|
121
|
-
|
|
122
|
-
// ── Helpers ──
|
|
123
|
-
|
|
124
|
-
function lastPart(): InputPart {
|
|
125
|
-
return parts[parts.length - 1]!;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/** Ensure the last part is a text part (for typing into). */
|
|
129
|
-
function ensureTrailingText(): TextPart {
|
|
130
|
-
const last = lastPart();
|
|
131
|
-
if (last.type === "text") return last;
|
|
132
|
-
const t: TextPart = { type: "text", content: "" };
|
|
133
|
-
parts.push(t);
|
|
134
|
-
return t;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function pasteTag(p: PastePart): string {
|
|
138
|
-
const lines = p.content.split("\n").length;
|
|
139
|
-
return lines > 1
|
|
140
|
-
? `[Pasted ~${lines} lines]`
|
|
141
|
-
: `[Pasted ${p.content.length} chars]`;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// ── Drawing ──
|
|
145
|
-
// Track how many visual rows the last render occupied.
|
|
146
|
-
// Move up to the first row, clear to end of screen, rewrite.
|
|
147
|
-
|
|
148
|
-
let prevRows = 1;
|
|
149
|
-
|
|
150
|
-
function redraw(): void {
|
|
151
|
-
const cols = process.stdout.columns || 80;
|
|
152
|
-
|
|
153
|
-
// Build display string and measure visible length (strip ANSI)
|
|
154
|
-
let display = promptStr;
|
|
155
|
-
let visLen = 4; // " ❯ " = 4 visible chars
|
|
156
|
-
for (const p of parts) {
|
|
157
|
-
if (p.type === "text") {
|
|
158
|
-
display += p.content;
|
|
159
|
-
visLen += p.content.length;
|
|
160
|
-
} else {
|
|
161
|
-
const tag = pasteTag(p);
|
|
162
|
-
display += pc.dim(tag);
|
|
163
|
-
visLen += tag.length;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Move cursor to start of the previous render, clear to end of screen
|
|
168
|
-
if (prevRows > 1) {
|
|
169
|
-
process.stdout.write(`\x1b[${prevRows - 1}A`); // move up
|
|
170
|
-
}
|
|
171
|
-
process.stdout.write(`\r\x1b[J${display}\x1b[?25h`); // col 0, clear to EOS, write, show cursor
|
|
172
|
-
|
|
173
|
-
prevRows = Math.max(1, Math.ceil(visLen / cols));
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
function getFullText(): string {
|
|
177
|
-
return partsText(parts);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function clear(): void {
|
|
181
|
-
parts = [{ type: "text", content: "" }];
|
|
182
|
-
history.resetNavigation();
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
function submit(): void {
|
|
186
|
-
const text = getFullText();
|
|
187
|
-
if (!pendingResolve) history.add(parts);
|
|
188
|
-
clear();
|
|
189
|
-
process.stdout.write("\n");
|
|
190
|
-
|
|
191
|
-
if (pendingResolve) {
|
|
192
|
-
const resolve = pendingResolve;
|
|
193
|
-
pendingResolve = null;
|
|
194
|
-
resolve(text);
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
if (lineCallback) lineCallback(text);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
function handlePasteComplete(text: string): void {
|
|
201
|
-
const lineCount = text.split("\n").length;
|
|
202
|
-
if (
|
|
203
|
-
lineCount >= PASTE_COLLAPSE_LINES ||
|
|
204
|
-
text.length > PASTE_COLLAPSE_CHARS
|
|
205
|
-
) {
|
|
206
|
-
// Collapse into a paste part
|
|
207
|
-
parts.push({ type: "paste", content: text });
|
|
208
|
-
} else {
|
|
209
|
-
// Short paste — inline into current text part
|
|
210
|
-
ensureTrailingText().content += text.replace(/\n/g, " ");
|
|
211
|
-
}
|
|
212
|
-
history.detach(parts);
|
|
213
|
-
redraw();
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
function handleBackspace(): void {
|
|
217
|
-
const last = lastPart();
|
|
218
|
-
if (last.type === "text" && last.content.length > 0) {
|
|
219
|
-
// Delete last char from text
|
|
220
|
-
last.content = last.content.slice(0, -1);
|
|
221
|
-
} else if (
|
|
222
|
-
last.type === "text" &&
|
|
223
|
-
last.content === "" &&
|
|
224
|
-
parts.length > 1
|
|
225
|
-
) {
|
|
226
|
-
// Empty trailing text — remove it, then remove the paste before it
|
|
227
|
-
parts.pop();
|
|
228
|
-
parts.pop();
|
|
229
|
-
// Ensure we always have at least one text part
|
|
230
|
-
if (parts.length === 0) parts.push({ type: "text", content: "" });
|
|
231
|
-
ensureTrailingText();
|
|
232
|
-
} else if (last.type === "paste") {
|
|
233
|
-
// Remove the paste block
|
|
234
|
-
parts.pop();
|
|
235
|
-
if (parts.length === 0) parts.push({ type: "text", content: "" });
|
|
236
|
-
ensureTrailingText();
|
|
237
|
-
}
|
|
238
|
-
history.detach(parts);
|
|
239
|
-
redraw();
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
function navigateHistory(direction: "previous" | "next"): void {
|
|
243
|
-
const recalled = history.move(direction, parts);
|
|
244
|
-
if (!recalled) return;
|
|
245
|
-
parts = recalled;
|
|
246
|
-
redraw();
|
|
247
|
-
}
|
|
34
|
+
const state = createInputState(promptStr);
|
|
248
35
|
|
|
249
36
|
// ── Raw mode ──
|
|
250
37
|
|
|
@@ -256,140 +43,38 @@ export function createInput(promptStr: string): InputHandler {
|
|
|
256
43
|
process.stdout.write("\x1b[?2004h");
|
|
257
44
|
|
|
258
45
|
process.stdin.on("data", (chunk: string) => {
|
|
259
|
-
if (paused) return;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
if (chunk.includes(PASTE_START)) {
|
|
263
|
-
inPaste = true;
|
|
264
|
-
pasteAccum = chunk.split(PASTE_START).slice(1).join(PASTE_START);
|
|
265
|
-
if (pasteAccum.includes(PASTE_END)) {
|
|
266
|
-
inPaste = false;
|
|
267
|
-
handlePasteComplete(pasteAccum.split(PASTE_END)[0]!);
|
|
268
|
-
pasteAccum = "";
|
|
269
|
-
}
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
if (inPaste) {
|
|
273
|
-
if (chunk.includes(PASTE_END)) {
|
|
274
|
-
pasteAccum += chunk.split(PASTE_END)[0]!;
|
|
275
|
-
inPaste = false;
|
|
276
|
-
handlePasteComplete(pasteAccum);
|
|
277
|
-
pasteAccum = "";
|
|
278
|
-
} else {
|
|
279
|
-
pasteAccum += chunk;
|
|
280
|
-
}
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// ── Normal input ──
|
|
285
|
-
for (let i = 0; i < chunk.length; i++) {
|
|
286
|
-
const ch = chunk[i]!;
|
|
287
|
-
const code = chunk.charCodeAt(i);
|
|
288
|
-
|
|
289
|
-
if (code === 0x03) {
|
|
290
|
-
// Ctrl+C
|
|
291
|
-
process.stdout.write("\n\x1b[?2004l");
|
|
292
|
-
if (process.stdin.isTTY) process.stdin.setRawMode(false);
|
|
293
|
-
process.exit(0);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
if (code === 0x15) {
|
|
297
|
-
// Ctrl+U
|
|
298
|
-
clear();
|
|
299
|
-
redraw();
|
|
300
|
-
continue;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
if (code === 0x0d || code === 0x0a) {
|
|
304
|
-
// Enter
|
|
305
|
-
if (getFullText()) {
|
|
306
|
-
submit();
|
|
307
|
-
} else {
|
|
308
|
-
process.stdout.write("\n");
|
|
309
|
-
redraw();
|
|
310
|
-
}
|
|
311
|
-
continue;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
if (code === 0x7f || code === 0x08) {
|
|
315
|
-
// Backspace
|
|
316
|
-
handleBackspace();
|
|
317
|
-
continue;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
if (code === 0x1b) {
|
|
321
|
-
if (i + 1 < chunk.length && chunk[i + 1] === "[") {
|
|
322
|
-
// CSI escape sequence. Up/Down navigate history; the rest are
|
|
323
|
-
// ignored until cursor editing is implemented.
|
|
324
|
-
let end = i + 2;
|
|
325
|
-
while (end < chunk.length && chunk.charCodeAt(end) < 0x40) end++;
|
|
326
|
-
const final = chunk[end];
|
|
327
|
-
if (final === "A") navigateHistory("previous");
|
|
328
|
-
if (final === "B") navigateHistory("next");
|
|
329
|
-
i = end;
|
|
330
|
-
} else if (
|
|
331
|
-
i + 2 < chunk.length &&
|
|
332
|
-
chunk[i + 1] === "O" &&
|
|
333
|
-
(chunk[i + 2] === "A" || chunk[i + 2] === "B")
|
|
334
|
-
) {
|
|
335
|
-
// Some terminals use application-cursor sequences (ESC O A/B).
|
|
336
|
-
navigateHistory(chunk[i + 2] === "A" ? "previous" : "next");
|
|
337
|
-
i += 2;
|
|
338
|
-
} else if (pendingResolve) {
|
|
339
|
-
// Bare Escape during waitForInput — cancel
|
|
340
|
-
const resolve = pendingResolve;
|
|
341
|
-
pendingResolve = null;
|
|
342
|
-
clear();
|
|
343
|
-
process.stdout.write("\n");
|
|
344
|
-
resolve("");
|
|
345
|
-
}
|
|
346
|
-
continue;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
if (code === 0x09) {
|
|
350
|
-
// Tab
|
|
351
|
-
ensureTrailingText().content += " ";
|
|
352
|
-
history.detach(parts);
|
|
353
|
-
redraw();
|
|
354
|
-
continue;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
if (code < 0x20) continue;
|
|
358
|
-
|
|
359
|
-
// Printable char
|
|
360
|
-
ensureTrailingText().content += ch;
|
|
361
|
-
history.detach(parts);
|
|
362
|
-
redraw();
|
|
363
|
-
}
|
|
46
|
+
if (state.paused) return;
|
|
47
|
+
if (consumePasteChunk(state, chunk)) return;
|
|
48
|
+
handleKeyChunk(state, chunk);
|
|
364
49
|
});
|
|
365
50
|
|
|
366
51
|
return {
|
|
367
52
|
onLine(callback) {
|
|
368
|
-
lineCallback = callback;
|
|
53
|
+
state.lineCallback = callback;
|
|
369
54
|
},
|
|
370
55
|
prompt() {
|
|
371
|
-
paused = false;
|
|
372
|
-
prevRows = 1; // fresh prompt = 1 row
|
|
373
|
-
redraw();
|
|
56
|
+
state.paused = false;
|
|
57
|
+
state.prevRows = 1; // fresh prompt = 1 row
|
|
58
|
+
redraw(state);
|
|
374
59
|
},
|
|
375
60
|
waitForInput(): Promise<string> {
|
|
376
61
|
return new Promise((resolve) => {
|
|
377
|
-
pendingResolve = resolve;
|
|
378
|
-
paused = false;
|
|
379
|
-
prevRows = 1;
|
|
380
|
-
redraw();
|
|
62
|
+
state.pendingResolve = resolve;
|
|
63
|
+
state.paused = false;
|
|
64
|
+
state.prevRows = 1;
|
|
65
|
+
redraw(state);
|
|
381
66
|
});
|
|
382
67
|
},
|
|
383
68
|
pause() {
|
|
384
|
-
paused = true;
|
|
69
|
+
state.paused = true;
|
|
385
70
|
},
|
|
386
71
|
resume() {
|
|
387
|
-
paused = false;
|
|
72
|
+
state.paused = false;
|
|
388
73
|
},
|
|
389
74
|
close() {
|
|
390
|
-
if (pendingResolve) {
|
|
391
|
-
const resolve = pendingResolve;
|
|
392
|
-
pendingResolve = null;
|
|
75
|
+
if (state.pendingResolve) {
|
|
76
|
+
const resolve = state.pendingResolve;
|
|
77
|
+
state.pendingResolve = null;
|
|
393
78
|
resolve("");
|
|
394
79
|
}
|
|
395
80
|
process.stdout.write("\x1b[?2004l");
|
|
@@ -11,7 +11,7 @@ import makeWASocket, { type AuthenticationState, type WASocket } from "baileys";
|
|
|
11
11
|
import qrcode from "qrcode-terminal";
|
|
12
12
|
import { log, logError, logWarn } from "../../util/log.js";
|
|
13
13
|
import { dirs } from "../../util/paths.js";
|
|
14
|
-
import { notifyAdmin } from "../../core/notify.js";
|
|
14
|
+
import { notifyAdmin } from "../../core/frontend-runtime/admin-notify.js";
|
|
15
15
|
import { useAtomicAuthState } from "./auth-state.js";
|
|
16
16
|
import { bareId } from "./identity.js";
|
|
17
17
|
import { handleInbound } from "./inbound.js";
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* (socket lifecycle, reconnect, park-until-paired).
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import type { TalonConfig } from "../../
|
|
22
|
+
import type { TalonConfig } from "../../core/config/index.js";
|
|
23
23
|
import type { ContextManager } from "../../core/types.js";
|
|
24
24
|
import type { Gateway } from "../../core/engine/gateway.js";
|
|
25
25
|
import { log, logError, logWarn } from "../../util/log.js";
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
pruneWhatsAppMessages,
|
|
33
33
|
} from "../../storage/whatsapp-messages.js";
|
|
34
34
|
import { flushAuthWrites } from "./auth-state.js";
|
|
35
|
-
import { registerPairingProvider } from "../../core/pairing-broker.js";
|
|
35
|
+
import { registerPairingProvider } from "../../core/frontend-runtime/pairing-broker.js";
|
|
36
36
|
import { beginPairingAttempt } from "./pairing-service.js";
|
|
37
37
|
import { runConnectionLoop } from "./connection.js";
|
|
38
38
|
import { lookupWhatsAppChat, type WhatsAppChatInfo } from "./registry.js";
|
|
@@ -16,7 +16,7 @@ import QRCode from "qrcode";
|
|
|
16
16
|
import type {
|
|
17
17
|
PairingAttempt,
|
|
18
18
|
PairingOutcome,
|
|
19
|
-
} from "../../core/pairing-broker.js";
|
|
19
|
+
} from "../../core/frontend-runtime/pairing-broker.js";
|
|
20
20
|
import { log, logError } from "../../util/log.js";
|
|
21
21
|
import { dirs } from "../../util/paths.js";
|
|
22
22
|
import { useAtomicAuthState, flushAuthWrites } from "./auth-state.js";
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type { WASocket } from "baileys";
|
|
12
|
-
import type { TalonConfig } from "../../
|
|
12
|
+
import type { TalonConfig } from "../../core/config/index.js";
|
|
13
13
|
import type { Gateway } from "../../core/engine/gateway.js";
|
|
14
14
|
import { bareId } from "./identity.js";
|
|
15
15
|
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
import { existsSync } from "node:fs";
|
|
24
24
|
import { homedir } from "node:os";
|
|
25
25
|
import { dirname, join, resolve } from "node:path";
|
|
26
|
-
import type { DoctorCheck } from "../../core/doctor.js";
|
|
26
|
+
import type { DoctorCheck } from "../../core/doctor/index.js";
|
|
27
27
|
import {
|
|
28
28
|
compareVersions,
|
|
29
29
|
expandHome,
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
17
17
|
import { homedir } from "node:os";
|
|
18
18
|
import { dirname, join, resolve } from "node:path";
|
|
19
|
-
import type { DoctorCheck } from "../../core/doctor.js";
|
|
19
|
+
import type { DoctorCheck } from "../../core/doctor/index.js";
|
|
20
20
|
import {
|
|
21
21
|
failDetail,
|
|
22
22
|
loadProvisionState,
|