Ctrl K
ComunidadGuías…

test/kiro-adapter-init.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 EventEmitter = require("node:events");

var { createKiroAdapter } = require("../lib/yoke/adapters/kiro");
var yoke = require("../lib/yoke");

function createHarness(outcomes) {
  var instances = [];

  function FakeAcpServer(binaryPath, options) {
    var proc = new EventEmitter();
    proc.exitCode = null;
    proc.signalCode = null;
    proc.kills = [];
    proc.kill = function(signal) {
      proc.kills.push(signal);
      proc.exitCode = 0;
      proc.emit("exit", 0, signal);
      return true;
    };

    this.proc = proc;
    this.options = options;
    this.started = false;
    this.index = instances.length;
    instances.push(this);
  }

  FakeAcpServer.prototype.start = function() {
    this.started = true;
    return Promise.resolve();
  };

  FakeAcpServer.prototype.send = function(method) {
    assert.strictEqual(method, "initialize");
    var outcome = outcomes[this.index];
    if (outcome instanceof Error) return Promise.reject(outcome);
    return Promise.resolve(outcome || { protocolVersion: 1 });
  };

  FakeAcpServer.prototype.addRequestHandler = function(method, fn) {
    this.requestHandlerMethod = method;
    this.requestHandler = fn;
  };

  FakeAcpServer.prototype.stop = function() {
    this.started = false;
    this.proc.kill("SIGTERM");
  };

  function createAdapter() {
    return createKiroAdapter({
      cwd: process.cwd(),
      _binaryPath: "/fake/kiro-cli",
      _AcpServerCtor: FakeAcpServer,
      _fetchModels: function() {
        return Promise.resolve({ models: ["auto"], defaultModel: "auto" });
      },
    });
  }

  return { instances: instances, createAdapter: createAdapter };
}

test("a failed init does not poison the next retry", async function() {
  var harness = createHarness([new Error("handshake failed"), null]);
  var adapter = harness.createAdapter();
  var firstAttempt = adapter.init();

  await assert.rejects(firstAttempt, /handshake failed/);

  var secondAttempt = adapter.init();
  assert.notStrictEqual(secondAttempt, firstAttempt);
  await secondAttempt;
  assert.strictEqual(harness.instances.length, 2);
});

test("Kiro forwards the scoped environment to its ACP process", async function() {
  var harness = createHarness([null]);
  var adapter = harness.createAdapter();
  await adapter.init({ env: { PROJECT_TOKEN: "scoped" } });
  assert.strictEqual(harness.instances[0].options.env.PROJECT_TOKEN, "scoped");
  await adapter.shutdown();
});

test("a failed init stops the spawned ACP child", async function() {
  var harness = createHarness([new Error("initialize timeout")]);
  var adapter = harness.createAdapter();

  await assert.rejects(adapter.init(), /initialize timeout/);

  assert.strictEqual(harness.instances.length, 1);
  assert.deepStrictEqual(harness.instances[0].proc.kills, ["SIGTERM"]);
  assert.strictEqual(harness.instances[0].started, false);
});

test("a started child without a completed handshake is not reported ready", async function() {
  var harness = createHarness([new Error("protocol mismatch"), { protocolVersion: 1 }]);
  var adapter = harness.createAdapter();

  await assert.rejects(adapter.init(), /protocol mismatch/);
  var ready = await adapter.init();

  assert.strictEqual(harness.instances.length, 2, "init must spawn a fresh child after handshake failure");
  assert.deepStrictEqual(ready.models, ["auto"]);
});

test("idle reclaim works after an init failure and successful retry", async function() {
  var harness = createHarness([new Error("logged out"), null]);
  var adapter = harness.createAdapter();

  await assert.rejects(adapter.init(), /logged out/);
  await adapter.init();
  await new Promise(function(resolve) { setTimeout(resolve, 5); });

  var reclaimed = await adapter.shutdownIfIdle(0);
  assert.strictEqual(reclaimed, true);
  assert.deepStrictEqual(harness.instances[1].proc.kills, ["SIGTERM"]);
});

test("lazy creation refuses Kiro for an OS-isolated user", async function() {
  var adapters = {};
  var result = await yoke.lazyCreateAdapter(adapters, "kiro", {
    cwd: process.cwd(),
    linuxUser: "clay-user",
  });

  assert.strictEqual(result, null);
  assert.deepStrictEqual(adapters, {});
});