@volter/supercode-teams 0.2.152 → 0.2.153

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/terminal-mail.mjs +17 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/supercode-teams",
3
- "version": "0.2.152",
3
+ "version": "0.2.153",
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
- const known = new Set([...this.state.pending.flatMap(m => m.ids), ...(this.state.active?.message_ids ?? []), ...this.state.receipts.flatMap(r => r.message_ids)]);
58
- if (messageIds.some(id => !known.has(id))) {
59
- // One caller retry is one queued envelope, including when a prior batch is
60
- // waiting for confirmation. New mail joins the next paste, never this one.
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 = this.state.pending.slice();
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
- this.log({ delivered: false, queued: true, batch: batch.id, message_ids: batch.message_ids, attempt: batch.enters });
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();