Gateway: watch API, pairing, notifications, APNs sender, CLI, tests
This commit is contained in:
1 parent
972f6e4be5
commit
6ca098b701
12 files changed
+1297
-1
No files matched your search
@@ -0,0 +1,104 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
|
||||
import type { BoundedThread, ThreadShell } from "../src/t3/types.ts";
|
||||
import { summarize, trimText } from "../src/views.ts";
|
||||
|
||||
const thread = (overrides: Partial<ThreadShell> = {}): ThreadShell => ({
|
||||
id: "thread-1",
|
||||
projectId: "project-1",
|
||||
title: "Receipt OCR",
|
||||
createdAt: "2026-11-01T09:00:00.000Z",
|
||||
updatedAt: "2026-11-01T09:00:00.000Z",
|
||||
status: "running",
|
||||
activeRunId: "run-1",
|
||||
pendingRuntimeRequest: null,
|
||||
modelSelection: { instanceId: "claudeAgent", model: "claude-opus-5-5" },
|
||||
lineage: { relationshipToParent: null },
|
||||
...overrides,
|
||||
});
|
||||
|
||||
const message = (role: string, text: string, id = text) => ({
|
||||
id,
|
||||
role,
|
||||
text,
|
||||
createdAt: "2026-11-01T09:00:00.000Z",
|
||||
updatedAt: "2026-11-01T09:00:00.000Z",
|
||||
});
|
||||
|
||||
const bounded = (turnItems: BoundedThread["projection"]["turnItems"], messages = [message("assistant", "Tests written.")]) =>
|
||||
({ snapshotSequence: 1, projection: { thread: thread(), messages, turnItems } }) as BoundedThread;
|
||||
|
||||
describe("trimText", () => {
|
||||
it("collapses whitespace and cuts at a word", () => {
|
||||
expect(trimText("one two\n\nthree", 50)).toBe("one two three");
|
||||
expect(trimText("alpha beta gamma delta", 15)).toBe("alpha beta…");
|
||||
});
|
||||
});
|
||||
|
||||
describe("summarize", () => {
|
||||
it("takes the last assistant message and skips empty or system ones", () => {
|
||||
const summary = summarize(
|
||||
bounded([], [message("user", "Add OCR"), message("assistant", "Done, all green."), message("system", "noise"), message("assistant", " ")]),
|
||||
thread(),
|
||||
);
|
||||
expect(summary.lastAssistantMessage).toBe("Done, all green.");
|
||||
expect(summary.messages.map((m) => m.role)).toEqual(["user", "assistant"]);
|
||||
});
|
||||
|
||||
it("reads the pending approval's prompt and options", () => {
|
||||
const summary = summarize(
|
||||
bounded([
|
||||
{
|
||||
type: "approval_request",
|
||||
requestId: "r1",
|
||||
requestKind: "command",
|
||||
prompt: "bun test --filter ocr",
|
||||
options: [
|
||||
{ decision: "accept", label: "Allow once" },
|
||||
{ decision: "acceptAlways", label: "Always allow", warning: "Applies to every thread" },
|
||||
{ decision: "decline", label: "Deny" },
|
||||
],
|
||||
} as BoundedThread["projection"]["turnItems"][number],
|
||||
]),
|
||||
thread({ pendingRuntimeRequest: { id: "r1", kind: "command", createdAt: "2026-11-01T09:00:00.000Z" } }),
|
||||
);
|
||||
expect(summary.request).toEqual({
|
||||
id: "r1",
|
||||
kind: "command",
|
||||
prompt: "bun test --filter ocr",
|
||||
reason: null,
|
||||
options: [
|
||||
{ decision: "accept", label: "Allow once" },
|
||||
{ decision: "acceptAlways", label: "Always allow" },
|
||||
{ decision: "decline", label: "Deny" },
|
||||
],
|
||||
questions: [],
|
||||
});
|
||||
});
|
||||
|
||||
it("offers Allow and Deny when the approval's turn item is not loaded yet", () => {
|
||||
const summary = summarize(
|
||||
bounded([]),
|
||||
thread({ pendingRuntimeRequest: { id: "r9", kind: "file-change", createdAt: "2026-11-01T09:00:00.000Z" } }),
|
||||
);
|
||||
expect(summary.request?.options.map((o) => o.decision)).toEqual(["accept", "decline"]);
|
||||
});
|
||||
|
||||
it("reads questions, using the label when an option has no value", () => {
|
||||
const summary = summarize(
|
||||
bounded([
|
||||
{
|
||||
type: "user_input_request",
|
||||
requestId: "q1",
|
||||
questions: [
|
||||
{ id: "db", header: "Database", question: "Which database?", options: [{ label: "SQLite", description: "" }] },
|
||||
],
|
||||
} as BoundedThread["projection"]["turnItems"][number],
|
||||
]),
|
||||
thread({ pendingRuntimeRequest: { id: "q1", kind: "user_input", createdAt: "2026-11-01T09:00:00.000Z" } }),
|
||||
);
|
||||
expect(summary.request?.questions).toEqual([
|
||||
{ id: "db", header: "Database", question: "Which database?", options: [{ label: "SQLite", value: "SQLite" }], allowCustomAnswer: false },
|
||||
]);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user