spb/khaelor Public
KHAELOR — a terminal-native autonomous engineering agent powered by Anthropic.
TypeScript 82.9%
HTML 14.9%
CSS 1.1%
JavaScript 0.7%
1/**2 * KHAELOR3 * File: src/agent/session-handle.ts4 * Description: KernelSession — the kernel's narrow handle onto the durable event log and bus.5 *6 * Author: Simon-Pierre Boucher7 * Contact: contact@spboucher.ai8 */910import { isDurableEvent } from "../session/index.js";11import type {12 DurableEvent,13 DurableEventInput,14 EphemeralEventInput,15 EventBus,16} from "../session/index.js";1718/**19 * What the agent layer needs from the Session Engine (ARCHITECTURE.md §4.1):20 * read the recorded durable stream and publish new events. Everything the21 * kernel "knows" is derived from `events()` — never from loop-local flags.22 */23export interface KernelSession {24 readonly sessionId: string;25 /** All durable events recorded so far, in seq order (replayed + live). */26 events(): readonly DurableEvent[];27 /** Append (write-ahead) + publish; returns the assigned envelope. */28 publishDurable(input: DurableEventInput): DurableEvent;29 /** Fire-and-forget streaming deltas — never persisted. */30 publishEphemeral(input: EphemeralEventInput): void;31}3233export interface EventLogSessionOptions {34 sessionId: string;35 /** The session bus (write-ahead appender already attached by the composition root). */36 bus: EventBus;37 /** Events replayed by `SessionLog.open()` — empty for a fresh session. */38 replayed?: readonly DurableEvent[];39}4041/**42 * Default KernelSession: an in-memory seq-ordered view over the bus.43 * Durable events published by ANY producer (kernel, executor, permission44 * service) land here synchronously because the bus dispatches write-ahead45 * appended envelopes before `publishDurable` returns (EVENT_MODEL.md §5.2).46 */47export class EventLogSession implements KernelSession {48 readonly sessionId: string;49 readonly #bus: EventBus;50 readonly #events: DurableEvent[];5152 constructor(options: EventLogSessionOptions) {53 this.sessionId = options.sessionId;54 this.#bus = options.bus;55 this.#events = [...(options.replayed ?? [])];56 this.#bus.onAny((event) => {57 if (isDurableEvent(event)) this.#events.push(event);58 });59 }6061 events(): readonly DurableEvent[] {62 return this.#events;63 }6465 publishDurable(input: DurableEventInput): DurableEvent {66 return this.#bus.publishDurable(input);67 }6869 publishEphemeral(input: EphemeralEventInput): void {70 this.#bus.publishEphemeral(input);71 }72}73