Clean up old stuff & fix ui errors
This commit is contained in:
@@ -51,6 +51,91 @@ describe('agent event normalization', () => {
|
||||
).toContainEqual({ kind: 'file_edited', path: 'src/app.ts' });
|
||||
});
|
||||
|
||||
test('normalizes current Codex item events', () => {
|
||||
expect(
|
||||
normalizeCodexJsonLine(
|
||||
JSON.stringify({
|
||||
type: 'item.completed',
|
||||
item: {
|
||||
id: 'item-1',
|
||||
type: 'agent_message',
|
||||
text: 'I updated the auth provider.',
|
||||
},
|
||||
}),
|
||||
),
|
||||
).toContainEqual({
|
||||
kind: 'assistant_delta',
|
||||
content: 'I updated the auth provider.',
|
||||
});
|
||||
|
||||
expect(
|
||||
normalizeCodexJsonLine(
|
||||
JSON.stringify({
|
||||
type: 'item.completed',
|
||||
item: {
|
||||
id: 'item-2',
|
||||
type: 'error',
|
||||
message: 'sandbox failed',
|
||||
},
|
||||
}),
|
||||
),
|
||||
).toContainEqual({
|
||||
kind: 'error',
|
||||
message: 'sandbox failed',
|
||||
});
|
||||
|
||||
expect(
|
||||
normalizeCodexJsonLine(
|
||||
JSON.stringify({
|
||||
type: 'turn.failed',
|
||||
error: { message: 'request failed' },
|
||||
}),
|
||||
),
|
||||
).toContainEqual({
|
||||
kind: 'error',
|
||||
message: '{\n "message": "request failed"\n}',
|
||||
});
|
||||
});
|
||||
|
||||
test('normalizes Codex tool item lifecycle events', () => {
|
||||
expect(
|
||||
normalizeCodexJsonLine(
|
||||
JSON.stringify({
|
||||
type: 'item.started',
|
||||
item: {
|
||||
id: 'tool-1',
|
||||
type: 'local_shell_call',
|
||||
command: ['bash', '-lc', 'rg Authentik'],
|
||||
},
|
||||
}),
|
||||
),
|
||||
).toContainEqual({
|
||||
kind: 'tool_started',
|
||||
name: 'local_shell_call',
|
||||
input: 'bash -lc rg Authentik',
|
||||
externalMessageId: 'tool-1',
|
||||
});
|
||||
|
||||
expect(
|
||||
normalizeCodexJsonLine(
|
||||
JSON.stringify({
|
||||
type: 'item.completed',
|
||||
item: {
|
||||
id: 'tool-1',
|
||||
type: 'local_shell_call',
|
||||
command: ['bash', '-lc', 'rg Authentik'],
|
||||
output: 'apps/web/auth.ts',
|
||||
},
|
||||
}),
|
||||
),
|
||||
).toContainEqual({
|
||||
kind: 'tool_completed',
|
||||
name: 'local_shell_call',
|
||||
output: 'apps/web/auth.ts',
|
||||
externalMessageId: 'tool-1',
|
||||
});
|
||||
});
|
||||
|
||||
test('normalizes OpenCode assistant, tool, and permission events', () => {
|
||||
expect(
|
||||
normalizeOpenCodeEvent({
|
||||
@@ -93,5 +178,21 @@ describe('agent event normalization', () => {
|
||||
body: 'Run bun test?',
|
||||
metadata: '{\n "permissionID": "perm-1",\n "message": "Run bun test?"\n}',
|
||||
});
|
||||
|
||||
expect(
|
||||
normalizeOpenCodeEvent({
|
||||
type: 'tool.output',
|
||||
properties: {
|
||||
tool: 'read',
|
||||
output: 'apps/web/auth.ts',
|
||||
messageID: 'message-2',
|
||||
},
|
||||
}),
|
||||
).toContainEqual({
|
||||
kind: 'tool_completed',
|
||||
name: 'read',
|
||||
output: 'apps/web/auth.ts',
|
||||
externalMessageId: 'message-2',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { mkdir, mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { afterEach, describe, expect, test } from 'vitest';
|
||||
|
||||
import { prepareCodexWorkspaceFiles } from '../../src/codex-runtime';
|
||||
|
||||
const tempDirs: string[] = [];
|
||||
|
||||
const mode = async (filePath: string) => (await stat(filePath)).mode & 0o777;
|
||||
|
||||
describe('Codex runtime preparation', () => {
|
||||
afterEach(async () => {
|
||||
await Promise.all(
|
||||
tempDirs.map((dir) => rm(dir, { force: true, recursive: true })),
|
||||
);
|
||||
tempDirs.length = 0;
|
||||
});
|
||||
|
||||
test('prepares writable Codex directories and preserves project config contents', async () => {
|
||||
const workdir = await mkdtemp(path.join(os.tmpdir(), 'spoon-codex-'));
|
||||
tempDirs.push(workdir);
|
||||
const repoDir = path.join(workdir, 'repo');
|
||||
await mkdir(path.join(repoDir, '.codex'), { recursive: true });
|
||||
const projectConfig = path.join(repoDir, '.codex', 'config.toml');
|
||||
await writeFile(projectConfig, '[features]\ncodex_hooks = true\n');
|
||||
|
||||
await prepareCodexWorkspaceFiles({ workdir, repoDir });
|
||||
|
||||
await expect(readFile(projectConfig, 'utf8')).resolves.toBe(
|
||||
'[features]\ncodex_hooks = true\n',
|
||||
);
|
||||
await expect(mode(workdir)).resolves.toBe(0o755);
|
||||
await expect(mode(repoDir)).resolves.toBe(0o755);
|
||||
await expect(mode(path.join(workdir, '.codex'))).resolves.toBe(0o755);
|
||||
await expect(mode(path.join(workdir, '.config'))).resolves.toBe(0o755);
|
||||
await expect(mode(path.join(workdir, '.local', 'share'))).resolves.toBe(
|
||||
0o755,
|
||||
);
|
||||
await expect(mode(path.join(repoDir, '.codex'))).resolves.toBe(0o755);
|
||||
await expect(mode(projectConfig)).resolves.toBe(0o644);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
|
||||
const loadVolumeSpec = async () => {
|
||||
vi.resetModules();
|
||||
process.env.SPOON_WORKER_TOKEN = 'test-worker-token';
|
||||
process.env.GITHUB_APP_ID = '123';
|
||||
process.env.GITHUB_APP_PRIVATE_KEY =
|
||||
'-----BEGIN PRIVATE KEY-----\\ntest\\n-----END PRIVATE KEY-----';
|
||||
return await import('../../src/runtime/docker');
|
||||
};
|
||||
|
||||
describe('Docker runtime', () => {
|
||||
afterEach(() => {
|
||||
delete process.env.SPOON_AGENT_CONTAINER_RUNTIME;
|
||||
delete process.env.SPOON_AGENT_CONTAINER_VOLUME_OPTIONS;
|
||||
vi.resetModules();
|
||||
});
|
||||
|
||||
test('adds SELinux relabel option for Podman workspace mounts by default', async () => {
|
||||
process.env.SPOON_AGENT_CONTAINER_RUNTIME = 'podman';
|
||||
const { jobWorkspaceVolumeSpec } = await loadVolumeSpec();
|
||||
|
||||
expect(jobWorkspaceVolumeSpec('/tmp/spoon-job')).toBe(
|
||||
'/tmp/spoon-job:/workspace:Z',
|
||||
);
|
||||
});
|
||||
|
||||
test('does not add Podman volume options for Docker by default', async () => {
|
||||
process.env.SPOON_AGENT_CONTAINER_RUNTIME = 'docker';
|
||||
const { jobWorkspaceVolumeSpec } = await loadVolumeSpec();
|
||||
|
||||
expect(jobWorkspaceVolumeSpec('/tmp/spoon-job')).toBe(
|
||||
'/tmp/spoon-job:/workspace',
|
||||
);
|
||||
});
|
||||
|
||||
test('allows explicit workspace mount options', async () => {
|
||||
process.env.SPOON_AGENT_CONTAINER_RUNTIME = 'podman';
|
||||
process.env.SPOON_AGENT_CONTAINER_VOLUME_OPTIONS = 'z';
|
||||
const { jobWorkspaceVolumeSpec } = await loadVolumeSpec();
|
||||
|
||||
expect(jobWorkspaceVolumeSpec('/tmp/spoon-job')).toBe(
|
||||
'/tmp/spoon-job:/workspace:z',
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user