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>
59 lines
1.7 KiB
TypeScript
59 lines
1.7 KiB
TypeScript
import { join } from 'path';
|
|
import { getEntityDir } from '../paths.js';
|
|
import { getNextId } from '../counter.js';
|
|
import { writeEntity } from '../files.js';
|
|
import { MemorySchema, type Memory } from '../schema.js';
|
|
import { Index } from '../index.js';
|
|
|
|
export function addMemory(cwd: string, options: Partial<Memory> = {}): Memory {
|
|
const now = new Date().toISOString();
|
|
const id = getNextId(cwd, 'memory');
|
|
const memory: Memory = MemorySchema.parse({
|
|
id,
|
|
title: options.title ?? 'Memory',
|
|
category: options.category ?? 'technical',
|
|
content: options.content ?? '',
|
|
tags: options.tags ?? [],
|
|
relatedTasks: options.relatedTasks ?? [],
|
|
relatedDecisions: options.relatedDecisions ?? [],
|
|
createdAt: now,
|
|
updatedAt: now,
|
|
tokens: options.tokens,
|
|
duration: options.duration,
|
|
by: options.by,
|
|
});
|
|
|
|
const filePath = join(getEntityDir(cwd, 'memory'), `${memory.id}.md`);
|
|
writeEntity(filePath, memory, `# ${memory.title}\n\n${memory.content}`);
|
|
|
|
const index = new Index(cwd);
|
|
index.upsert({
|
|
id: memory.id,
|
|
type: 'memory',
|
|
title: memory.title,
|
|
content: memory.content,
|
|
filePath,
|
|
createdAt: memory.createdAt,
|
|
updatedAt: memory.updatedAt,
|
|
tags: JSON.stringify(memory.tags),
|
|
relatedTasks: JSON.stringify(memory.relatedTasks),
|
|
});
|
|
index.close();
|
|
|
|
return memory;
|
|
}
|
|
|
|
export function searchMemory(cwd: string, query: string): ReturnType<Index['search']> {
|
|
const index = new Index(cwd);
|
|
const results = index.search(query);
|
|
index.close();
|
|
return results;
|
|
}
|
|
|
|
export function listMemory(cwd: string): ReturnType<Index['list']> {
|
|
const index = new Index(cwd);
|
|
const memories = index.list('memory');
|
|
index.close();
|
|
return memories;
|
|
}
|