mirror of
https://github.com/davidkaya/aryx.git
synced 2026-07-24 13:38:43 +02:00
Remove the entire patterns domain model, IPC channels, sidecar services, renderer components, and tests. Sessions now bind exclusively to workflows via workflowId. Builtin workflows replace builtin patterns. Backend: - Make AgentNodeConfig standalone (no longer extends PatternAgentDefinition) - Add WorkflowOrchestrationMode and WorkflowExecutionDefinition - Create builtin workflows (single-agent, sequential, concurrent, handoff, group-chat) - Rewrite session model config helpers for workflow-only - Remove pattern IPC channels, handlers, and preload bindings - Merge createSession/createWorkflowSession into single method - Remove sidecar PatternGraphResolver, PatternValidator, pattern DTOs - Add workspace migration for legacy sessions (patternId -> workflowId) Frontend: - Delete PatternEditor, pattern-graph components, patternGraph lib - Delete NewSessionModal (session creation uses workflows directly) - Remove PatternsSection from SettingsPanel - Update App.tsx, ChatPane, ActivityPanel, Sidebar, RunTimeline, AgentConfigFields, InlinePills, sessionActivity to use workflow types - Delete pattern.ts domain module 78 files changed across backend and frontend. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
105 lines
3.6 KiB
TypeScript
105 lines
3.6 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, mock, test } from 'bun:test';
|
|
import { access, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
import { join } from 'node:path';
|
|
|
|
import { createScratchpadProject } from '@shared/domain/project';
|
|
import type { SessionRecord } from '@shared/domain/session';
|
|
import { createWorkspaceSeed, type WorkspaceState } from '@shared/domain/workspace';
|
|
|
|
const TIMESTAMP = '2026-03-28T00:00:00.000Z';
|
|
const USER_DATA_PATH = 'C:\\workspace\\personal\\repositories\\aryx\\tests\\fixtures';
|
|
|
|
mock.module('electron', () => {
|
|
const electronMock = {
|
|
app: {
|
|
getPath: () => USER_DATA_PATH,
|
|
},
|
|
};
|
|
|
|
return {
|
|
...electronMock,
|
|
default: electronMock,
|
|
};
|
|
});
|
|
|
|
const { WorkspaceRepository } = await import('@main/persistence/workspaceRepository');
|
|
|
|
function createStoredWorkspace(): WorkspaceState {
|
|
const workspace = createWorkspaceSeed();
|
|
const scratchpadProject = createScratchpadProject('C:\\legacy\\scratchpad', TIMESTAMP);
|
|
const workflowId = workspace.workflows[0]?.id;
|
|
if (!workflowId) {
|
|
throw new Error('Expected workspace seed to include at least one pattern.');
|
|
}
|
|
|
|
const session: SessionRecord = {
|
|
id: 'session-scratchpad',
|
|
projectId: scratchpadProject.id,
|
|
workflowId,
|
|
title: 'Scratchpad',
|
|
createdAt: TIMESTAMP,
|
|
updatedAt: TIMESTAMP,
|
|
status: 'idle',
|
|
messages: [],
|
|
runs: [],
|
|
};
|
|
|
|
return {
|
|
...workspace,
|
|
projects: [scratchpadProject],
|
|
sessions: [session],
|
|
selectedProjectId: scratchpadProject.id,
|
|
selectedWorkflowId: workflowId,
|
|
selectedSessionId: session.id,
|
|
};
|
|
}
|
|
|
|
beforeEach(async () => {
|
|
await rm(join(USER_DATA_PATH, 'workspace.json'), { force: true });
|
|
await rm(join(USER_DATA_PATH, 'scratchpad'), { recursive: true, force: true });
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await rm(join(USER_DATA_PATH, 'workspace.json'), { force: true });
|
|
await rm(join(USER_DATA_PATH, 'scratchpad'), { recursive: true, force: true });
|
|
});
|
|
|
|
describe('WorkspaceRepository scratchpad migration', () => {
|
|
test('assigns per-session scratchpad directories while loading existing workspace state', async () => {
|
|
const workspaceFilePath = join(USER_DATA_PATH, 'workspace.json');
|
|
await mkdir(USER_DATA_PATH, { recursive: true });
|
|
await writeFile(workspaceFilePath, JSON.stringify(createStoredWorkspace(), null, 2), 'utf8');
|
|
|
|
const repository = new WorkspaceRepository();
|
|
const loaded = await repository.load();
|
|
const loadedSession = loaded.sessions[0];
|
|
if (!loadedSession) {
|
|
throw new Error('Expected load() to return the migrated scratchpad session.');
|
|
}
|
|
|
|
const expectedScratchpadPath = join(USER_DATA_PATH, 'scratchpad');
|
|
const expectedSessionPath = join(expectedScratchpadPath, loadedSession.id);
|
|
|
|
expect(loaded.projects[0]?.path).toBe(expectedScratchpadPath);
|
|
expect(loadedSession.cwd).toBe(expectedSessionPath);
|
|
await access(expectedSessionPath);
|
|
|
|
const persisted = JSON.parse(await readFile(workspaceFilePath, 'utf8')) as WorkspaceState;
|
|
expect(persisted.sessions[0]?.cwd).toBe(expectedSessionPath);
|
|
});
|
|
|
|
test('strips runtime MCP probing state before persisting workspace data', async () => {
|
|
const workspaceFilePath = join(USER_DATA_PATH, 'workspace.json');
|
|
await mkdir(USER_DATA_PATH, { recursive: true });
|
|
|
|
const repository = new WorkspaceRepository();
|
|
const workspace = createStoredWorkspace();
|
|
workspace.mcpProbingServerIds = ['server-a', 'server-b'];
|
|
|
|
await repository.save(workspace);
|
|
|
|
const persisted = JSON.parse(await readFile(workspaceFilePath, 'utf8')) as WorkspaceState;
|
|
expect('mcpProbingServerIds' in persisted).toBe(false);
|
|
});
|
|
});
|