@volter/supercode-teams 0.3.182 → 0.3.184

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/live-sessions.mjs CHANGED
@@ -851,12 +851,15 @@ async function ancestryOf(pid, timeout = 5000) {
851
851
  async function rolloutSession(pid, thread, timeout = 5000) {
852
852
  const out = await new Promise((resolve) => execFile(tool('lsof'), ['-a', '-p', String(pid), '-Fn'], { timeout, maxBuffer: 16 * 1024 * 1024 }, (_error, stdout) => resolve(String(stdout ?? ''))));
853
853
  const rollouts = [...new Set(out.split('\n').filter((line) => line.startsWith('n') && /rollout-[^/]*\.jsonl$/.test(line)).map((line) => line.slice(1)))];
854
- if (!rollouts.some((path) => path.includes(thread))) return null;
854
+ // the thread each rollout is of, by the id its file is named with: the claim is one of those ids whole, never a part
855
+ // of a path (a rollout's name also carries its date, in the same letters a thread id is checked for)
856
+ const idOf = (path) => /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/.exec(path)?.[1] ?? null;
857
+ if (!rollouts.some((path) => idOf(path) === thread)) return null;
855
858
  if (rollouts.length === 1) return thread;
856
859
  // each thread held, with the thread that spawned it (none for one a person started)
857
860
  const parentOf = new Map();
858
861
  for (const path of rollouts) {
859
- const id = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/.exec(path)?.[1];
862
+ const id = idOf(path);
860
863
  const first = rolloutHead(path);
861
864
  if (!id || first === null) return null;
862
865
  parentOf.set(id, /"parent_thread_id"\s*:\s*"([0-9a-f-]{8,64})"/.exec(first)?.[1] ?? null);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/supercode-teams",
3
- "version": "0.3.182",
3
+ "version": "0.3.184",
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
@@ -264,6 +264,23 @@ export class TerminalMailbox {
264
264
  batch.error = 'codex-update-prompt: delivery retained; restart Codex with check_for_update_on_startup=false';
265
265
  this.save(); this.log({ delivered: false, queued: true, reason: batch.error, message_ids: batch.message_ids }); return;
266
266
  }
267
+ if (batch.kind === 'codex' && batch.phase === 'pasted' && batch.enters >= 3 && Date.now() - batch.last_enter >= 5000) {
268
+ // Every Enter is spent and the transcript, read above from the paste's own offset, holds no such message. A
269
+ // composer that reads empty with no turn running holds neither the paste nor a turn that could still take it
270
+ // (Codex writes a message entered during a turn when that turn takes it or ends): this paste will never be
271
+ // confirmed, and left active it holds every later message behind it for good. It is refused, never pasted
272
+ // again, and the queue moves on. Read twice, then the transcript once more; a draft, a running turn or an
273
+ // unreadable screen leaves the batch waiting on its transcript.
274
+ let lost = true;
275
+ for (let check = 0; lost && check < 2; check++) {
276
+ const screen = await this.host.capture(this.session.id, { lines: 200, preserveEscapes: true });
277
+ lost = composerText(batch.kind, screen) === '' && !/\besc to (?:interrupt|cancel)\b/iu.test(screen);
278
+ if (lost && check === 0) await pause(200);
279
+ }
280
+ if (lost && !confirmed(batch)) {
281
+ await this.recordRefusal(batch, 'native transcript unconfirmed after Enter retries; composer empty'); return;
282
+ }
283
+ }
267
284
  if (batch.kind === 'claude-code' && batch.phase === 'prepared' && batch.expiresAt && Date.now() >= batch.expiresAt) {
268
285
  await this.recordRefusal(batch, 'delivery deadline elapsed; no input pasted'); return;
269
286
  }