OXYGENHUB
◆ main spectra-vscode / test / smoke.mjs
2.5 KiB · last changed Spectra for VS Code 0.1: set up and chat without the command line (#6) 1 day ago source blame history raw
1
// Smoke test against a real Spectra (not part of `npm test`): the bridge
2
// signs, the model fills from the API, the stream delivers, a brief saved
3
// through the API reaches Spectra. Run with: npm run smoke
4
import { spawn, execFileSync } from "node:child_process";
5
import { mkdtempSync, rmSync } from "node:fs";
6
import { tmpdir } from "node:os";
7
import { join } from "node:path";
8
import assert from "node:assert/strict";
9
10
const bin = process.env.SPECTRA_BIN;
11
assert.ok(bin, "set SPECTRA_BIN to a spectra binary");
12
const dir = mkdtempSync(join(process.env.SMOKE_DIR || tmpdir(), "spectra-smoke-"));
13
const env = { ...process.env, HOME: dir, SPECTRA_HOME: join(dir, "owner"), SPECTRA_DATA: join(dir, "data"), XDG_DATA_HOME: join(dir, "xdg"), NO_COLOR: "1" };
14
Object.assign(process.env, env);
15
const sp = (...a) => execFileSync(bin, a, { env }).toString();
16
sp("identity", "create", "--name", "Smoke Owner");
17
sp("init");
18
sp("project", "add", "book", "-d", "the manuscript");
19
sp("agent", "add", "claude-book", "--kind", "claude-code", "--project", "book", "--home", join(dir, "agents/claude-book"), "--yes");
20
const serve = spawn(bin, ["serve", "--bind", "127.0.0.1:0"], { env, stdio: "ignore" });
21
await new Promise((r) => setTimeout(r, 1500));
22
23
const { Bridge } = await import("../out/smoke-bridge.mjs");
24
const { Model } = await import("../out/smoke-model.mjs");
25
const log = { append() {}, appendLine() {} };
26
const bridge = new Bridge(log);
27
const model = new Model(bridge);
28
try {
29
  await model.refresh();
30
  assert.equal(model.error, undefined);
31
  assert.equal(model.brief.actor, "human");
32
  assert.equal(model.agents[0].name, "claude-book");
33
  assert.ok(model.channels.some((c) => c.name === "book"));
34
35
  const seen = [];
36
  model.onEvent((e) => seen.push(e.kind));
37
  model.start();
38
  await new Promise((r) => setTimeout(r, 800));
39
  await bridge.request("POST", "/api/v1/channels/book/messages", { body: "hello from the editor" });
40
  await bridge.request("PUT", "/api/v1/briefs", { project: "book", text: "Chapter 3 becomes chapter 5." });
41
  await new Promise((r) => setTimeout(r, 1200));
42
  assert.ok(seen.includes("message.posted"), `the stream delivered: ${seen}`);
43
  assert.equal(model.briefs.projects[0]?.text, "Chapter 3 becomes chapter 5.");
44
  assert.match(sp("brief", "show", "--project", "book"), /chapter 5/);
45
  console.log("smoke: ok");
46
} finally {
47
  model.dispose();
48
  bridge.dispose();
49
  serve.kill("SIGTERM");
50
  await new Promise((r) => setTimeout(r, 1500));
51
  rmSync(dir, { recursive: true, force: true });
52
}