@turns/dev 0.0.19 → 0.0.21

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.
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawn } from 'node:child_process';
3
+ import { createHash } from 'node:crypto';
3
4
  import fs from 'node:fs';
4
5
  import net from 'node:net';
5
6
  import os from 'node:os';
@@ -208,6 +209,7 @@ class LineTransport {
208
209
  */
209
210
  const CLAUDE_NOTIFICATION_RESULT_GRACE_MS = 2_000;
210
211
  class ClaudeTransport extends LineTransport {
212
+ nativeTurnActive = false;
211
213
  sessionId;
212
214
  permissionMode;
213
215
  turnWaiter;
@@ -245,9 +247,28 @@ class ClaudeTransport extends LineTransport {
245
247
  this.turnWaiter = null;
246
248
  this.control = new Map();
247
249
  }
250
+ setNativeTurnActive(active) {
251
+ if (this.nativeTurnActive === active)
252
+ return;
253
+ this.nativeTurnActive = active;
254
+ if (this.anchor.transport === this && this.anchor.status === 'idle')
255
+ this.anchor.scheduleExit();
256
+ }
248
257
  onFrame(frame) {
249
258
  if (!frame || typeof frame !== 'object')
250
259
  return;
260
+ // Background notifications can start native turns after the queued prompt
261
+ // has completed. Retain the process until the root result, including quiet
262
+ // foreground tools and gaps between streamed messages. Child results do
263
+ // not complete the root turn, and child output alone does not start one.
264
+ if (!frame.parent_tool_use_id) {
265
+ if (frame.type === 'result')
266
+ this.setNativeTurnActive(false);
267
+ else if (frame.type === 'stream_event' ||
268
+ frame.type === 'assistant' ||
269
+ (frame.type === 'system' && frame.subtype === 'status' && frame.status === 'requesting'))
270
+ this.setNativeTurnActive(true);
271
+ }
251
272
  // Another turn starting means a held notification result was not the
252
273
  // prompt's: keep waiting for the result of the turn now running.
253
274
  if (this.heldResult &&
@@ -302,6 +323,7 @@ class ClaudeTransport extends LineTransport {
302
323
  : waiter.resolve(frame);
303
324
  }
304
325
  onClose(error) {
326
+ this.setNativeTurnActive(false);
305
327
  if (this.heldResult) {
306
328
  clearTimeout(this.heldResult.timer);
307
329
  this.heldResult = null;
@@ -577,7 +599,12 @@ class CodexAppServerTransport extends LineTransport {
577
599
  asyncQuestionsSeen = new Set();
578
600
  constructor(anchor) {
579
601
  const profile = { command: 'codex' };
580
- const mcp = `mcp_servers.turns={command=${JSON.stringify(process.execPath)},args=[${JSON.stringify(questionMcpPath)}],env={TURNS_AGENT_ANCHOR_SOCKET=${JSON.stringify(socketPath)}}}`;
602
+ // Codex deep-merges CLI overrides with configured MCP servers. Reusing
603
+ // "turns" mixes our stdio command with a user's HTTP URL and prevents even
604
+ // thread/start from loading its config. Keep the helper stable per anchor,
605
+ // but outside user-configured names, without rewriting their config.
606
+ const mcpName = `turns_anchor_${createHash('sha256').update(socketPath).digest('hex').slice(0, 12)}`;
607
+ const mcp = `mcp_servers.${mcpName}={command=${JSON.stringify(process.execPath)},args=[${JSON.stringify(questionMcpPath)}],env={TURNS_AGENT_ANCHOR_SOCKET=${JSON.stringify(socketPath)}}}`;
581
608
  super(anchor, 'app-server', resolveHarnessCommand('codex', profile), ['-c', mcp, 'app-server', '--listen', 'stdio://'], anchor.cwd);
582
609
  this.threadId = anchor.agentSessionId;
583
610
  this.permissionMode = anchor.permissionMode;
@@ -1654,7 +1681,10 @@ class Anchor {
1654
1681
  }
1655
1682
  scheduleExit() {
1656
1683
  clearTimeout(this.idleTimer);
1657
- if (this.status === 'running' || this.pendingInteractions.size || this.transport?.backgroundTasks?.active) {
1684
+ if (this.status === 'running' ||
1685
+ this.pendingInteractions.size ||
1686
+ this.transport?.backgroundTasks?.active ||
1687
+ this.transport?.nativeTurnActive) {
1658
1688
  this.idleTimer = null;
1659
1689
  return;
1660
1690
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@turns/dev",
3
- "version": "0.0.19",
3
+ "version": "0.0.21",
4
4
  "description": "Upload local AI agent sessions to turns.dev",
5
5
  "license": "MIT",
6
6
  "type": "module",