@volter/supercode-teams 0.2.152 → 0.2.154
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 +3 -2
- package/package.json +1 -1
- package/terminal-mail.mjs +17 -7
package/machine.mjs
CHANGED
|
@@ -1556,6 +1556,7 @@ export class TeamsMachine extends MachineCore {
|
|
|
1556
1556
|
const session = await this.#paneByContext(params.pane);
|
|
1557
1557
|
if (!session) throw new Error(`no pane with context ${params.pane}`);
|
|
1558
1558
|
const doc = readJson(this.p.suspended, { v: 1, panes: {} });
|
|
1559
|
+
let delivery;
|
|
1559
1560
|
if (method === 'panes.suspend') {
|
|
1560
1561
|
this.suspended.add(params.pane);
|
|
1561
1562
|
doc.panes[params.pane] = { at: Date.now(), by: principal };
|
|
@@ -1563,11 +1564,11 @@ export class TeamsMachine extends MachineCore {
|
|
|
1563
1564
|
} else {
|
|
1564
1565
|
this.suspended.delete(params.pane);
|
|
1565
1566
|
delete doc.panes[params.pane];
|
|
1566
|
-
if (params.input) await this.host.sendInput(session.id, submission(params.input), { submitMode: params.submitMode ?? 'single' });
|
|
1567
1567
|
}
|
|
1568
1568
|
writeJson(this.p.suspended, doc);
|
|
1569
|
+
if (method === 'panes.resume' && params.input) delivery = await this.#deliverPaneText(session, params.pane, params.input, { messageIds: params.message_ids });
|
|
1569
1570
|
act(method, `pane:${params.pane}`, 'ok', method === 'panes.resume' && params.input ? 'with input' : null);
|
|
1570
|
-
return { pane: params.pane, suspended: method === 'panes.suspend' };
|
|
1571
|
+
return { pane: params.pane, suspended: method === 'panes.suspend', ...(delivery ? { delivery } : {}) };
|
|
1571
1572
|
}
|
|
1572
1573
|
case 'panes.input': {
|
|
1573
1574
|
// Input as a request (the terminal host's own sendInput, with its paste/settle/submit
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/supercode-teams",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.154",
|
|
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",
|
package/terminal-mail.mjs
CHANGED
|
@@ -36,7 +36,7 @@ export class TerminalMailbox {
|
|
|
36
36
|
mkdirSync(this.dir, { recursive: true, mode: 0o700 });
|
|
37
37
|
this.file = join(this.dir, 'queue.json'); this.log = log; this.load = load;
|
|
38
38
|
try { this.state = JSON.parse(readFileSync(this.file, 'utf8')); }
|
|
39
|
-
catch (error) { if (error.code !== 'ENOENT') throw error; this.state = { recipient, pending: [], active: null, receipts: [] }; }
|
|
39
|
+
catch (error) { if (error.code !== 'ENOENT') throw error; this.state = { recipient, pending: [], active: null, receipts: [], accepted: {} }; }
|
|
40
40
|
this.work = null;
|
|
41
41
|
}
|
|
42
42
|
save() {
|
|
@@ -54,10 +54,14 @@ export class TerminalMailbox {
|
|
|
54
54
|
}
|
|
55
55
|
enqueue(text, ids, identity, host, session) {
|
|
56
56
|
const messageIds = ids?.length ? ids : [`input-${randomUUID()}`];
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
if (messageIds.some(id => typeof id !== 'string' || !/^[A-Za-z0-9_-]{1,160}$/.test(id))) throw new Error('invalid terminal message id');
|
|
58
|
+
const digest = hash(text);
|
|
59
|
+
const accepted = this.state.accepted = Object.assign(Object.create(null), this.state.accepted ?? {});
|
|
60
|
+
const previous = messageIds.filter(id => accepted[id]);
|
|
61
|
+
if (previous.some(id => accepted[id] !== digest) || (previous.length && previous.length !== messageIds.length)) throw new Error('terminal message ids must retry the same complete envelope');
|
|
62
|
+
if (!previous.length) {
|
|
63
|
+
for (const id of messageIds) accepted[id] = digest;
|
|
64
|
+
// New mail joins the next paste while the current one awaits its receipt.
|
|
61
65
|
this.state.pending.push({ ids: messageIds, text }); this.save();
|
|
62
66
|
}
|
|
63
67
|
this.identity = identity; this.host = host; this.session = session;
|
|
@@ -75,7 +79,11 @@ export class TerminalMailbox {
|
|
|
75
79
|
async drain() {
|
|
76
80
|
let batch = this.state.active;
|
|
77
81
|
if (!batch && this.state.pending.length) {
|
|
78
|
-
const items =
|
|
82
|
+
const items = []; let size = 0;
|
|
83
|
+
for (const message of this.state.pending) {
|
|
84
|
+
if (items.length && size + Buffer.byteLength(message.text) > 32768) break;
|
|
85
|
+
items.push(message); size += Buffer.byteLength(message.text);
|
|
86
|
+
}
|
|
79
87
|
const text = items.map(m => m.text).join('\n\n');
|
|
80
88
|
const incremental = this.identity.kind === 'codex';
|
|
81
89
|
const baseline = incremental ? null : await this.load(this.identity.locator, { message_tail: 1 });
|
|
@@ -105,7 +113,9 @@ export class TerminalMailbox {
|
|
|
105
113
|
if (batch.enters < 3 && Date.now() - batch.last_enter >= 5000) {
|
|
106
114
|
batch.enters += 1; batch.last_enter = Date.now(); this.save();
|
|
107
115
|
await this.host.sendInput(this.session.id, '\r', { submitMode: 'single' });
|
|
108
|
-
|
|
116
|
+
const attempt = { delivered: false, queued: true, batch: batch.id, message_ids: batch.message_ids, attempt: batch.enters, at: Date.now() };
|
|
117
|
+
appendFileSync(join(this.dir, 'attempts.jsonl'), JSON.stringify(attempt) + '\n', { mode: 0o600 });
|
|
118
|
+
this.log(attempt);
|
|
109
119
|
}
|
|
110
120
|
batch.error = batch.enters >= 3 ? 'native transcript unconfirmed after Enter retries' : 'native transcript confirmation pending';
|
|
111
121
|
this.save();
|