GET /tasks/:id/activity returns a time-sorted ActivityItem[] assembled from existing data (task created, handoffs by taskId, memory by relatedTasks, current status). memory add + task done gain optional tokens/duration/by metadata surfaced in the timeline. Board cards expand inline to show the timeline. Index gains taskId + relatedTasks columns with migrations. 74 -> 97 tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
63 lines
2.2 KiB
TypeScript
63 lines
2.2 KiB
TypeScript
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
import { mkdtempSync, rmSync } from 'fs';
|
|
import { tmpdir } from 'os';
|
|
import { join } from 'path';
|
|
import { addMemory, searchMemory, listMemory } from '../src/core/services/memoryService.js';
|
|
import { Index } from '../src/core/index.js';
|
|
|
|
describe('memoryService', () => {
|
|
let cwd: string;
|
|
|
|
beforeEach(() => { cwd = mkdtempSync(join(tmpdir(), 'ah-mem-')); });
|
|
afterEach(() => { rmSync(cwd, { recursive: true, force: true }); });
|
|
|
|
it('creates and searches memory', () => {
|
|
const m = addMemory(cwd, { title: 'DNS cache', category: 'technical', content: 'Use TTL' });
|
|
expect(m.id.startsWith('MEM-')).toBe(true);
|
|
expect(searchMemory(cwd, 'TTL')).toHaveLength(1);
|
|
expect(listMemory(cwd)).toHaveLength(1);
|
|
});
|
|
|
|
it('stores relatedTasks in the memory object', () => {
|
|
const m = addMemory(cwd, {
|
|
title: 'TTL lesson',
|
|
category: 'lesson',
|
|
content: 'Use short TTL',
|
|
relatedTasks: ['TSK-0001', 'TSK-0002'],
|
|
});
|
|
expect(m.relatedTasks).toEqual(['TSK-0001', 'TSK-0002']);
|
|
});
|
|
|
|
it('stores optional tokens, duration, by fields', () => {
|
|
const m = addMemory(cwd, {
|
|
title: 'Perf stats',
|
|
category: 'implementation',
|
|
content: 'p99=50ms',
|
|
tokens: 1500,
|
|
duration: 30_000,
|
|
by: 'kimi',
|
|
});
|
|
expect(m.tokens).toBe(1500);
|
|
expect(m.duration).toBe(30_000);
|
|
expect(m.by).toBe('kimi');
|
|
});
|
|
|
|
it('listMemoryByTask returns entries linked to a given task', () => {
|
|
addMemory(cwd, { title: 'Related', category: 'technical', content: 'x', relatedTasks: ['TSK-0042'] });
|
|
addMemory(cwd, { title: 'Unrelated', category: 'technical', content: 'y', relatedTasks: ['TSK-0099'] });
|
|
const index = new Index(cwd);
|
|
const results = index.listMemoryByTask('TSK-0042');
|
|
index.close();
|
|
expect(results).toHaveLength(1);
|
|
expect(results[0].title).toBe('Related');
|
|
});
|
|
|
|
it('listMemoryByTask returns empty when no memory is linked', () => {
|
|
addMemory(cwd, { title: 'Other', category: 'technical', content: 'y', relatedTasks: ['TSK-0099'] });
|
|
const index = new Index(cwd);
|
|
const results = index.listMemoryByTask('TSK-0001');
|
|
index.close();
|
|
expect(results).toHaveLength(0);
|
|
});
|
|
});
|