Something went wrong. Try again.
A local-first event pipeline for independent agents, built on Jazz.
Something went wrong. Try again.
3.6 kB · 97 lines
TypeScript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798import { spawn } from "node:child_process";import fs from "node:fs/promises";import path from "node:path";import { afterEach, describe, expect, test } from "vitest";import { temporaryProject } from "./helpers.js";
const roots: string[] = [];
afterEach(async () => { await Promise.all(roots.splice(0).map((root) => fs.rm(root, { recursive: true, force: true })));});
describe("thought stream focus commands", () => { test("proposes an inert focus idempotently and lists body-dark receipts", async () => { const root = await temporaryProject("thoughtstream-focus-cli-"); roots.push(root); const declaration = path.join(process.cwd(), "focuses", "news.yaml"); const first = await run(["--silent", "thought", "stream", "focus-propose", "--file", declaration], { THOUGHTSTREAM_ROOT: root, }); const repeated = await run(["--silent", "thought", "stream", "focus-propose", "--file", declaration], { THOUGHTSTREAM_ROOT: root, }); const listed = await run(["--silent", "thought", "stream", "focus-list"], { THOUGHTSTREAM_ROOT: root, });
expect(first.code).toBe(0); expect(first.stderr).toBe(""); expect(repeated.code).toBe(0); expect(listed.code).toBe(0); expect(first.stdout).not.toContain("change Cameron's model of the world"); const firstOutput = JSON.parse(first.stdout) as { focusProposal: Record<string, unknown> }; const repeatedOutput = JSON.parse(repeated.stdout) as { focusProposal: Record<string, unknown> }; const listOutput = JSON.parse(listed.stdout) as { focusProposals: Array<Record<string, unknown>> }; expect(Object.keys(firstOutput.focusProposal).sort()).toEqual([ "authority", "declarationFingerprint", "eventId", "focusId", "focusVersion", "inserted", ]); expect(firstOutput).toMatchObject({ focusProposal: { focusId: "news", focusVersion: 1, inserted: true, authority: "proposal-only", }, }); expect(repeatedOutput).toMatchObject({ focusProposal: { inserted: false } }); expect(listOutput).toMatchObject({ focusProposals: [ { focusId: "news", focusVersion: 1, parentFocusIds: [], proposalSchemaVersion: 1, }, ], }); expect(Object.keys(listOutput.focusProposals[0]!).sort()).toEqual([ "declarationFingerprint", "eventId", "focusId", "focusVersion", "observedAt", "parentFocusIds", "proposalSchemaVersion", ]); expect(listed.stdout).not.toContain("change Cameron's model of the world"); for (const output of [firstOutput, repeatedOutput, listOutput]) { const serialized = JSON.stringify(output); expect(serialized).not.toContain('"declaration"'); expect(serialized).not.toContain('"scope"'); expect(serialized).not.toContain('"objective"'); expect(serialized).not.toContain('"permissions"'); } }, 20_000);});
async function run(args: string[], extraEnv: Record<string, string>): Promise<{ code: number | null; stdout: string; stderr: string }> { return new Promise((resolve, reject) => { const child = spawn("pnpm", args, { cwd: process.cwd(), env: { ...process.env, ...extraEnv }, stdio: ["ignore", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.on("data", (chunk) => { stdout += String(chunk); }); child.stderr.on("data", (chunk) => { stderr += String(chunk); }); child.once("error", reject); child.once("exit", (code) => resolve({ code, stdout, stderr })); });}