Ctrl K
ComunidadGuías…

test/codex-app-server-routing.test.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
var test = require("node:test");
var assert = require("node:assert");

var { CodexAppServer, buildSpawnSpec } = require("../lib/yoke/codex-app-server");

function makeServer() {
  var server = new CodexAppServer("/nonexistent/codex", {});
  server.started = true;
  server.proc = { stdin: { write: function() { return true; } } };
  server.written = [];
  server._write = function(msg) { server.written.push(msg); };
  return server;
}

test("routes Codex events to the handler bound to their thread", function() {
  var server = makeServer();
  var seenA = [];
  var seenB = [];
  var handlerA = server.addHandler(function(msg) { seenA.push(msg); });
  var handlerB = server.addHandler(function(msg) { seenB.push(msg); });
  handlerA.threadId = "thread-a";
  handlerB.threadId = "thread-b";

  server._handleMessage({ method: "item/agentMessage/delta", params: { threadId: "thread-a", delta: "hello" } });

  assert.strictEqual(seenA.length, 1);
  assert.strictEqual(seenB.length, 0);
});

test("a temporary query does not steal an existing Codex session handler", function() {
  var server = makeServer();
  var sessionEvents = [];
  var titleEvents = [];
  var sessionHandler = server.addHandler(function(msg) { sessionEvents.push(msg); });
  var titleHandler = server.addHandler(function(msg) { titleEvents.push(msg); });
  sessionHandler.threadId = "session-thread";
  titleHandler.threadId = "title-thread";

  server._handleMessage({ method: "turn/completed", params: { threadId: "session-thread" } });

  assert.strictEqual(sessionEvents.length, 1, "the original session must retain its events");
  assert.strictEqual(titleEvents.length, 0, "the title query must not receive another thread's events");
});

test("removing a temporary handler leaves existing Codex handlers active", function() {
  var server = makeServer();
  var sessionEvents = [];
  var sessionHandler = server.addHandler(function(msg) { sessionEvents.push(msg); });
  var titleHandler = server.addHandler(function() {});
  sessionHandler.threadId = "session-thread";
  titleHandler.threadId = "title-thread";

  server.removeHandler(titleHandler);
  server._handleMessage({ method: "turn/started", params: { threadId: "session-thread" } });

  assert.strictEqual(sessionEvents.length, 1);
  assert.strictEqual(server.handlers.length, 1);
});

test("fans process-wide Codex events out to every active handler", function() {
  var server = makeServer();
  var calls = 0;
  var handlerA = server.addHandler(function() { calls++; });
  var handlerB = server.addHandler(function() { calls++; });
  handlerA.threadId = "thread-a";
  handlerB.threadId = "thread-b";

  server._handleMessage({ method: "error", params: { error: { message: "transport failed" } } });

  assert.strictEqual(calls, 2);
});

test("rejects an unroutable Codex request instead of dropping it", function() {
  var server = makeServer();
  var handler = server.addHandler(function() { assert.fail("should not be called"); });
  handler.threadId = "thread-a";

  server._handleMessage({ id: 7, method: "item/commandExecution/requestApproval", params: { threadId: "missing-thread" } });

  assert.strictEqual(server.written.length, 1);
  assert.strictEqual(server.written[0].id, 7);
  assert.ok(server.written[0].error);
});

test("builds an OS-user Codex spawn without leaking the daemon environment", function() {
  var previousSecret = process.env.CLAY_TEST_DAEMON_SECRET;
  process.env.CLAY_TEST_DAEMON_SECRET = "must-not-leak";
  var wrappedOptions = null;
  try {
    var spec = buildSpawnSpec("/usr/bin/codex", ["app-server"], {
      cwd: "/workspace",
      env: { OPENAI_API_KEY: "user-key" },
      osUserInfo: {
        uid: 1201,
        gid: 1202,
        home: "/home/alice",
        user: "alice",
        shell: "/bin/bash",
      },
    }, function(command, args, options) {
      wrappedOptions = options;
      return { command: command, args: args, options: options };
    });

    assert.strictEqual(spec.command, "/usr/bin/codex");
    assert.strictEqual(wrappedOptions.uid, 1201);
    assert.strictEqual(wrappedOptions.gid, 1202);
    assert.strictEqual(wrappedOptions.env.HOME, "/home/alice");
    assert.strictEqual(wrappedOptions.env.USER, "alice");
    assert.strictEqual(wrappedOptions.env.OPENAI_API_KEY, "user-key");
    assert.strictEqual(wrappedOptions.env.CLAY_TEST_DAEMON_SECRET, undefined);
  } finally {
    if (previousSecret === undefined) delete process.env.CLAY_TEST_DAEMON_SECRET;
    else process.env.CLAY_TEST_DAEMON_SECRET = previousSecret;
  }
});