166b065ad4
Add in-place session renewal, searchable model selection, clearer progress feedback, tool-result previews, and per-session presentation state. Keep commands, errors, loading, and lifecycle indicators attached to their owning runtime so parallel tabs cannot interfere.
91 lines
3.5 KiB
JavaScript
91 lines
3.5 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { readFile } from "node:fs/promises";
|
|
import test from "node:test";
|
|
|
|
const sources = Promise.all([
|
|
readFile("ui/src/App.tsx", "utf8"),
|
|
readFile("ui/src/workspace/reducer.ts", "utf8"),
|
|
readFile("ui/src/workspace/useWorkspace.ts", "utf8"),
|
|
readFile("ui/src/workspace/persistence.ts", "utf8"),
|
|
readFile("ui/src/App.css", "utf8"),
|
|
]);
|
|
|
|
test("wires the desktop to stable runtime workspace APIs", async () => {
|
|
const [app, reducer, hook] = await sources;
|
|
for (const operation of [
|
|
"create_session_runtime",
|
|
"open_session_runtime",
|
|
"close_session_runtime",
|
|
"list_directory_sessions",
|
|
"get_session_runtime_snapshot",
|
|
"renew_session",
|
|
"subscribe_workspace",
|
|
])
|
|
assert.match(`${app}\n${hook}`, new RegExp(operation));
|
|
assert.doesNotMatch(app, /switch_session/);
|
|
assert.doesNotMatch(app, /["']new_session["']/);
|
|
assert.match(reducer, /WorkspaceState\["runtimesById"\]/);
|
|
assert.match(reducer, /requestGeneration/);
|
|
assert.match(reducer, /loadedThroughSeq/);
|
|
});
|
|
|
|
test("keeps presentation persistence allowlisted and agent IDs ephemeral", async () => {
|
|
const [, , , persistence] = await sources;
|
|
assert.match(persistence, /load_ui_state/);
|
|
assert.match(persistence, /save_ui_state/);
|
|
assert.match(persistence, /directoryOrder/);
|
|
assert.match(persistence, /drafts/);
|
|
assert.doesNotMatch(persistence, /agentId/);
|
|
assert.doesNotMatch(persistence, /messages/);
|
|
assert.doesNotMatch(persistence, /extensions/);
|
|
});
|
|
|
|
test("renders directory sidebar, accessible session tabs, warnings, and reduced motion", async () => {
|
|
const [app, , , , css] = await sources;
|
|
const [sidebar, tabs] = await Promise.all([
|
|
readFile("ui/src/components/DirectorySidebar.tsx", "utf8"),
|
|
readFile("ui/src/components/SessionTabs.tsx", "utf8"),
|
|
]);
|
|
assert.match(sidebar, /aria-label="Directories"/);
|
|
assert.match(tabs, /role="tablist"/);
|
|
assert.match(tabs, /role="tab"/);
|
|
assert.match(tabs, /aria-selected/);
|
|
assert.match(tabs, /ArrowRight/);
|
|
assert.match(app, /Multiple sessions are open in the same directory/);
|
|
assert.match(app, /Many Pi sessions are open/);
|
|
assert.match(css, /prefers-reduced-motion/);
|
|
assert.match(css, /grid-template-columns:\s*178px minmax\(0, 1fr\)/);
|
|
assert.match(
|
|
css,
|
|
/\.session-row-content\s*>\s*strong\s*\{[^}]*color:\s*#f1f3f4/s,
|
|
);
|
|
});
|
|
|
|
test("preserves native session naming, compaction, composer, and extension responses", async () => {
|
|
const [app] = await sources;
|
|
const [conversation, extension] = await Promise.all([
|
|
readFile("ui/src/components/ConversationWorkspace.tsx", "utf8"),
|
|
readFile("ui/src/components/ExtensionDialog.tsx", "utf8"),
|
|
]);
|
|
assert.match(app, /set_session_name/);
|
|
assert.match(app, /compact/);
|
|
assert.match(app, /submit_prompt/);
|
|
assert.match(app, /respond_to_extension/);
|
|
assert.match(conversation, /event\.key === "Enter" && !event\.shiftKey/);
|
|
assert.match(conversation, /className="todos-pane"/);
|
|
assert.match(extension, /role="dialog"/);
|
|
assert.match(extension, /aria-modal="true"/);
|
|
});
|
|
|
|
test("configures native window behavior and folder dialog capabilities", async () => {
|
|
const [config, capability, cargo] = await Promise.all([
|
|
readFile("ui/src-tauri/tauri.conf.json", "utf8"),
|
|
readFile("ui/src-tauri/capabilities/default.json", "utf8"),
|
|
readFile("ui/src-tauri/Cargo.toml", "utf8"),
|
|
]);
|
|
assert.match(config, /"width"\s*:\s*1100/);
|
|
assert.match(capability, /core:window:allow-start-dragging/);
|
|
assert.match(cargo, /tauri-plugin-single-instance/);
|
|
assert.match(cargo, /tauri-plugin-dialog/);
|
|
});
|