import fs from "node:fs/promises"; import path from "node:path"; import YAML from "yaml"; import type { JsonObject } from "../core/json.js"; import type { AppendEventResult } from "../events/types.js"; import type { JazzThoughtStore } from "../jazz/store.js"; import { FOCUS_DECLARATION_PROPOSED_EVENT_TYPE, FOCUS_DECLARATION_SCHEMA_VERSION, FOCUS_DECLARATION_SOURCE, focusDeclarationFingerprint, focusDeclarationProposalPayloadSchema, focusDeclarationSchema, type FocusDeclaration, } from "./types.js"; export * from "./types.js"; export interface FocusProposalSummary { eventId: string; focusId: string; focusVersion: number; parentFocusIds: string[]; declarationFingerprint: string; proposalSchemaVersion: number; observedAt: string; } export async function loadFocusDeclaration(file: string): Promise { const absolute = path.resolve(file); const stat = await fs.lstat(absolute); if (!stat.isFile() || stat.isSymbolicLink()) throw new Error("Focus declaration must be a regular nonsymlink file"); return focusDeclarationSchema.parse(YAML.parse(await fs.readFile(absolute, "utf8"))); } export async function proposeFocusDeclaration( store: JazzThoughtStore, declaration: FocusDeclaration, options: { actor?: string; occurredAt?: string; source?: string } = {}, ): Promise { const parsed = focusDeclarationSchema.parse(declaration); const identity = `${parsed.id}@${parsed.version}`; const fingerprint = focusDeclarationFingerprint(parsed); const payload = focusDeclarationProposalPayloadSchema.parse({ declaration: parsed, declarationFingerprint: fingerprint, resolution: { eventTypes: "unchecked", sourcePatterns: "unchecked", requestedPermissions: "unchecked", parentLineage: "unchecked", }, authority: { activatesFocus: false, expandsDataAccess: false, grantsExternalActions: false, startsTraining: false, promotesAdapter: false, }, }); return store.appendEvent({ type: FOCUS_DECLARATION_PROPOSED_EVENT_TYPE, schemaVersion: FOCUS_DECLARATION_SCHEMA_VERSION, source: options.source ?? FOCUS_DECLARATION_SOURCE, sourceKind: "system", externalId: identity, idempotencyKey: `focus-declaration:${identity}`, occurredAt: options.occurredAt ?? new Date().toISOString(), actor: options.actor ?? "operator:local", correlationId: `focus-declaration:${identity}`, privacy: "sensitive", payload: payload as unknown as JsonObject, }); } export async function listFocusProposals(store: JazzThoughtStore): Promise { const events = await store.listEvents({ types: [FOCUS_DECLARATION_PROPOSED_EVENT_TYPE] }); return events.filter((event) => event.schemaVersion === FOCUS_DECLARATION_SCHEMA_VERSION).map((event) => { const payload = focusDeclarationProposalPayloadSchema.parse(event.payload); return { eventId: event.id, focusId: payload.declaration.id, focusVersion: payload.declaration.version, parentFocusIds: payload.declaration.parentFocusIds, declarationFingerprint: payload.declarationFingerprint, proposalSchemaVersion: event.schemaVersion, observedAt: event.observedAt, }; }); }