@volter/supercode-teams 0.2.122 → 0.2.124
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/machine.mjs +35 -8
- package/package.json +1 -1
package/machine.mjs
CHANGED
|
@@ -1294,7 +1294,7 @@ export class TeamsMachine extends MachineCore {
|
|
|
1294
1294
|
if (!whole && !observesPanes(admitted)) need('view', '*');
|
|
1295
1295
|
const sessions = (await this.host.listSessions()).filter(s => s.contextKey && (whole || holds(admitted, 'observe', `pane:${s.contextKey}`)));
|
|
1296
1296
|
return Promise.all(sessions.map(async session => {
|
|
1297
|
-
const screen = await this.host.capture(session.id, { lines: 100, preserveEscapes: true }).catch(() => null);
|
|
1297
|
+
const screen = await Promise.resolve().then(() => this.host.capture(session.id, { lines: 100, preserveEscapes: true })).catch(() => null);
|
|
1298
1298
|
const kind = this.#paneKind(session.contextKey, session);
|
|
1299
1299
|
const composer = screen && terminal.composerText?.(kind, screen);
|
|
1300
1300
|
return { pane: session.contextKey, idleComposer: composer != null && !/\besc to (?:interrupt|cancel)\b/iu.test(screen) };
|
|
@@ -1485,17 +1485,44 @@ export class TeamsMachine extends MachineCore {
|
|
|
1485
1485
|
const screen = await this.host.capture(session.id, { lines: 200, preserveEscapes: true });
|
|
1486
1486
|
return /\besc to (?:interrupt|cancel)\b/iu.test(screen) ? null : terminal.composerText(kind, screen);
|
|
1487
1487
|
};
|
|
1488
|
+
const painted = await read();
|
|
1489
|
+
await new Promise(resolve => setTimeout(resolve, COMPOSER_RECHECK_MS));
|
|
1490
|
+
if (painted === null || painted !== await read()) return { cleared: false, reason: 'composer-not-stable' };
|
|
1491
|
+
// Native stderr can paint over the composer without entering its editor.
|
|
1492
|
+
// Repaint first so that a stale error line is not mistaken for a draft.
|
|
1493
|
+
await this.host.sendInput(session.id, '\u000c', { submitMode: 'none' });
|
|
1494
|
+
await new Promise(resolve => setTimeout(resolve, COMPOSER_RECHECK_MS));
|
|
1488
1495
|
const before = await read();
|
|
1489
1496
|
await new Promise(resolve => setTimeout(resolve, COMPOSER_RECHECK_MS));
|
|
1490
1497
|
if (before === null || before !== await read()) return { cleared: false, reason: 'composer-not-stable' };
|
|
1491
|
-
if (before === '')
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1498
|
+
if (before === '') {
|
|
1499
|
+
act('control', `pane:${params.pane}`, 'draft-cleared');
|
|
1500
|
+
return { cleared: true, alreadyEmpty: painted === '', repainted: painted !== '' };
|
|
1501
|
+
}
|
|
1502
|
+
if (before !== painted) return { cleared: false, reason: 'composer-changed' };
|
|
1503
|
+
// Clear whole drafts, including lines before an empty final line. Each deletion
|
|
1504
|
+
// must leave only text from the previous reading; a concurrent edit stops us.
|
|
1505
|
+
let remaining = before, cleared = false, reason = 'composer-not-empty';
|
|
1506
|
+
for (let line = 0; line < before.split('\n').length + 2; line += 1) {
|
|
1507
|
+
if (remaining !== await read()) { reason = 'composer-changed'; break; }
|
|
1508
|
+
await this.host.sendInput(session.id, '\u0005\u0015', { submitMode: 'none' });
|
|
1509
|
+
await new Promise(resolve => setTimeout(resolve, COMPOSER_RECHECK_MS));
|
|
1510
|
+
let after = await read();
|
|
1511
|
+
if (after === '') { cleared = true; break; }
|
|
1512
|
+
if (after === null || !remaining.includes(after)) { reason = 'composer-changed'; break; }
|
|
1513
|
+
// Kill-left left the cursor at the line's start. Backspace joins the
|
|
1514
|
+
// preceding line; it never submits or interrupts the session.
|
|
1515
|
+
remaining = after;
|
|
1516
|
+
if (remaining !== await read()) { reason = 'composer-changed'; break; }
|
|
1517
|
+
await this.host.sendInput(session.id, '\u007f', { submitMode: 'none' });
|
|
1518
|
+
await new Promise(resolve => setTimeout(resolve, COMPOSER_RECHECK_MS));
|
|
1519
|
+
after = await read();
|
|
1520
|
+
if (after === '') { cleared = true; break; }
|
|
1521
|
+
if (after === null || !remaining.replace(/\n/g, '').includes(after.replace(/\n/g, ''))) { reason = 'composer-changed'; break; }
|
|
1522
|
+
remaining = after;
|
|
1523
|
+
}
|
|
1497
1524
|
act('control', `pane:${params.pane}`, cleared ? 'draft-cleared' : 'draft-clear-unconfirmed');
|
|
1498
|
-
return { cleared, reason: cleared ? null :
|
|
1525
|
+
return { cleared, reason: cleared ? null : reason, beforeHash: createHash('sha256').update(before).digest('hex') };
|
|
1499
1526
|
} finally { this.inputInFlight.delete(session.id); }
|
|
1500
1527
|
}
|
|
1501
1528
|
case 'panes.turn': {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/supercode-teams",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.124",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A machine daemon serving this machine's doors, and a local or remote Teams server for shared session discovery, OpenTelemetry ingestion and access to enrolled machines.",
|
|
6
6
|
"license": "MIT",
|