beadboard/src/lib/activity.ts
zenchantlive ab051952bd feat(logic): establish derived-activity engine and agent-session protocols
Today we reached a major architectural conclusion: project history shouldn't be stored, it should be derived. We rejected the overhead of a separate SQLite event store in favor of an O(N) snapshot-diffing engine that computes human-readable narratives directly from the issues.jsonl source of truth.

Key Triumphs:
- Implemented O(N) diffing algorithm in src/lib/snapshot-differ.ts that transforms raw JSONL into 16 distinct social event types.
- Engineered a file-based persistence layer (src/lib/activity-persistence.ts) to solve the 'Next.js HMR Wiped My Memory' bug, ensuring project heartbeat survives server restarts.
- Developed the agent-session data model that unifies Beads, Activity, and Cross-Agent Mail into a single 'Mission' context.

Raw Honest Moment:
We struggled for over an hour with 'missing history' before realizing that development-mode reloads were purging our in-memory buffers. The shift to a file-backed ring buffer was a reactive pivot that became a core project strength.
2026-02-14 00:19:59 -08:00

75 lines
1.8 KiB
TypeScript

import type { BeadIssueWithProject } from './types';
/**
* 16 transition types for timeline activity events,
* as required by the bb-xhm.1 event model specification.
*/
export type ActivityEventKind =
| 'created'
| 'closed'
| 'reopened'
| 'status_changed'
| 'priority_changed'
| 'assignee_changed'
| 'type_changed'
| 'title_changed'
| 'description_changed'
| 'labels_changed'
| 'dependency_added'
| 'dependency_removed'
| 'comment_added'
| 'due_date_changed'
| 'estimate_changed'
| 'field_changed';
/**
* Represents a discrete change or action derived from bead snapshots or interactions.
*/
export interface ActivityEvent {
/** Unique identity for the event instance (likely UUID) */
id: string;
/** The type of transition that occurred */
kind: ActivityEventKind;
/** The issue this event belongs to */
beadId: string;
/** Display title of the issue at the time of the event */
beadTitle: string;
/** The project key this issue belongs to */
projectId: string;
/** Human-readable project name */
projectName: string;
/** ISO8601 timestamp of when the event was detected or recorded */
timestamp: string;
/** The actor who performed the action (assignee, owner, or session ID) */
actor: string | null;
/** Data payload describing the change */
payload: {
/** The specific field name that changed (for property updates) */
field?: string;
/** The previous value before the transition */
from?: any;
/** The new value after the transition */
to?: any;
/** Optional context message (e.g. comment text or close reason) */
message?: string;
};
}
/**
* A pair of snapshots used by the diffing engine to derive ActivityEvents.
*/
export interface SnapshotDiff {
previous: BeadIssueWithProject | null;
current: BeadIssueWithProject;
}