office-core 0.1.1 → 0.1.3
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.
|
@@ -182,7 +182,6 @@ async function processRoomMessages(runtime) {
|
|
|
182
182
|
}
|
|
183
183
|
return;
|
|
184
184
|
}
|
|
185
|
-
const runnableSessions = Array.from(sessions.values()).filter((session) => session.status === "running");
|
|
186
185
|
const project = await getJson(runtime, `/api/projects/${runtime.projectId}`).catch(() => null);
|
|
187
186
|
for (const message of messages) {
|
|
188
187
|
hooks.onRoomMessage?.(message, runtime);
|
|
@@ -190,6 +189,7 @@ async function processRoomMessages(runtime) {
|
|
|
190
189
|
runtime.roomCursorSeq = Math.max(runtime.roomCursorSeq, message.seq);
|
|
191
190
|
continue;
|
|
192
191
|
}
|
|
192
|
+
const runnableSessions = Array.from(sessions.values()).filter((session) => session.status === "running");
|
|
193
193
|
const targetSessions = runnableSessions.filter((session) => shouldSessionReceiveMessage(runtime, session, message, settings));
|
|
194
194
|
if (targetSessions.length === 0) {
|
|
195
195
|
console.log(`[room] seq=${message.seq} no sessions matched (runnable=${runnableSessions.length}), skipping`);
|
|
@@ -124,16 +124,37 @@ function findCmd(name) {
|
|
|
124
124
|
let _menuLines = 0;
|
|
125
125
|
let _menuSelection = 0;
|
|
126
126
|
let _menuScrollOffset = 0;
|
|
127
|
+
let _menuQuery = "";
|
|
127
128
|
const MAX_VISIBLE_SLASH_ITEMS = 6;
|
|
128
129
|
function getSlashMatches(partial) {
|
|
129
130
|
const q = partial.toLowerCase();
|
|
130
131
|
return CMDS.filter((c) => c.name.startsWith(q) || c.alias?.some((a) => a.startsWith(q)));
|
|
131
132
|
}
|
|
132
|
-
function
|
|
133
|
-
|
|
133
|
+
function eraseSlashMenu() {
|
|
134
|
+
if (_menuLines === 0)
|
|
135
|
+
return;
|
|
136
|
+
process.stdout.write(`\x1b[s\n`);
|
|
137
|
+
clearScreenDown(process.stdout);
|
|
138
|
+
process.stdout.write(`\x1b[u`);
|
|
139
|
+
_menuLines = 0;
|
|
140
|
+
}
|
|
141
|
+
function resetSlashMenuState() {
|
|
142
|
+
_menuSelection = 0;
|
|
143
|
+
_menuScrollOffset = 0;
|
|
144
|
+
_menuQuery = "";
|
|
145
|
+
}
|
|
146
|
+
function renderSlashMenu(partial, preserveSelection = false) {
|
|
147
|
+
eraseSlashMenu();
|
|
148
|
+
if (!preserveSelection || partial !== _menuQuery) {
|
|
149
|
+
_menuSelection = 0;
|
|
150
|
+
_menuScrollOffset = 0;
|
|
151
|
+
}
|
|
152
|
+
_menuQuery = partial;
|
|
134
153
|
const hits = getSlashMatches(partial);
|
|
135
|
-
if (hits.length === 0)
|
|
154
|
+
if (hits.length === 0) {
|
|
155
|
+
resetSlashMenuState();
|
|
136
156
|
return;
|
|
157
|
+
}
|
|
137
158
|
_menuSelection = Math.max(0, Math.min(_menuSelection, hits.length - 1));
|
|
138
159
|
if (_menuSelection < _menuScrollOffset) {
|
|
139
160
|
_menuScrollOffset = _menuSelection;
|
|
@@ -167,14 +188,29 @@ function renderSlashMenu(partial) {
|
|
|
167
188
|
_menuLines = lines.length;
|
|
168
189
|
}
|
|
169
190
|
function clearSlashMenu() {
|
|
170
|
-
|
|
191
|
+
eraseSlashMenu();
|
|
192
|
+
resetSlashMenuState();
|
|
193
|
+
}
|
|
194
|
+
let _menuRefreshPending = false;
|
|
195
|
+
let _queuedPreserveSelection = false;
|
|
196
|
+
function scheduleSlashMenuRefresh(rl, preserveSelection = false) {
|
|
197
|
+
_queuedPreserveSelection ||= preserveSelection;
|
|
198
|
+
if (_menuRefreshPending) {
|
|
171
199
|
return;
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
200
|
+
}
|
|
201
|
+
_menuRefreshPending = true;
|
|
202
|
+
setImmediate(() => {
|
|
203
|
+
_menuRefreshPending = false;
|
|
204
|
+
const keepSelection = _queuedPreserveSelection;
|
|
205
|
+
_queuedPreserveSelection = false;
|
|
206
|
+
const line = rl.line ?? "";
|
|
207
|
+
if (line.startsWith("/") && line.length >= 1) {
|
|
208
|
+
renderSlashMenu(line.slice(1), keepSelection);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
clearSlashMenu();
|
|
212
|
+
}
|
|
213
|
+
});
|
|
178
214
|
}
|
|
179
215
|
// ─── Tab Completer ──────────────────────────────────────────────────────────
|
|
180
216
|
function completer(line) {
|
|
@@ -571,8 +607,8 @@ async function main() {
|
|
|
571
607
|
const rl = createInterface({
|
|
572
608
|
input: process.stdin,
|
|
573
609
|
output: process.stdout,
|
|
574
|
-
completer,
|
|
575
610
|
terminal: isInteractiveTerminal,
|
|
611
|
+
historySize: 0,
|
|
576
612
|
});
|
|
577
613
|
const ctx = { runtime: null, rl, running: true, isInteractiveTerminal };
|
|
578
614
|
const sentIds = new Set();
|
|
@@ -608,16 +644,16 @@ async function main() {
|
|
|
608
644
|
key.name === "up"
|
|
609
645
|
? (_menuSelection + hits.length - 1) % hits.length
|
|
610
646
|
: (_menuSelection + 1) % hits.length;
|
|
611
|
-
|
|
647
|
+
scheduleSlashMenuRefresh(rl, true);
|
|
612
648
|
return;
|
|
613
649
|
}
|
|
614
650
|
if (hits.length > 0 && key?.name === "tab") {
|
|
615
651
|
const selected = hits[_menuSelection] ?? hits[0];
|
|
616
652
|
replaceInputLine(rl, `/${selected.name} `);
|
|
617
|
-
|
|
653
|
+
scheduleSlashMenuRefresh(rl, false);
|
|
618
654
|
return;
|
|
619
655
|
}
|
|
620
|
-
|
|
656
|
+
scheduleSlashMenuRefresh(rl, false);
|
|
621
657
|
}
|
|
622
658
|
else {
|
|
623
659
|
clearSlashMenu();
|
|
@@ -667,13 +703,16 @@ async function main() {
|
|
|
667
703
|
sentIds.add(messageId);
|
|
668
704
|
console.log(`${GRN}[${ts()}]${R} ${BOLD}You${R}: ${input}`);
|
|
669
705
|
try {
|
|
670
|
-
await postRoomMessageUpsert(ctx.runtime, {
|
|
706
|
+
const result = await postRoomMessageUpsert(ctx.runtime, {
|
|
671
707
|
message_id: messageId,
|
|
672
708
|
author_type: "user",
|
|
673
709
|
author_id: ctx.runtime.hostId,
|
|
674
710
|
author_label: "You",
|
|
675
711
|
text: input,
|
|
676
712
|
});
|
|
713
|
+
if (result?.message_id && result.message_id !== messageId) {
|
|
714
|
+
sentIds.add(String(result.message_id));
|
|
715
|
+
}
|
|
677
716
|
}
|
|
678
717
|
catch (e) {
|
|
679
718
|
sentIds.delete(messageId);
|