Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
34 lines
1.6 KiB
TypeScript
34 lines
1.6 KiB
TypeScript
import type { DatabaseSync } from "node:sqlite";
|
|
|
|
interface GoalState {
|
|
title: string;
|
|
description: string;
|
|
status: string;
|
|
}
|
|
|
|
/** Returns a notice whenever the run's goal is rewritten or closed after the run started, once per change. */
|
|
export function createGoalChangePoller(db: DatabaseSync, goalId: string | null): () => string | null {
|
|
if (!goalId) return () => null;
|
|
const read = () => db.prepare("select title, description, status from goals where id = ?").get(goalId) as GoalState | undefined;
|
|
let seen = read();
|
|
return () => {
|
|
const now = read();
|
|
if (!seen || !now || (now.title === seen.title && now.description === seen.description && now.status === seen.status)) return null;
|
|
const before = seen;
|
|
seen = now;
|
|
console.info(`[task-run] goal ${goalId} changed mid-run (${now.status}); notifying the session`);
|
|
if (now.status !== before.status && now.status !== "active") {
|
|
return `The goal for this work ("${now.title}") is now ${now.status}. Stop starting new work on it: wrap up, report what you finished, and set this task's status.`;
|
|
}
|
|
return `The goal for this work changed while you were working. It now reads: "${now.title}" — ${now.description} Re-check your plan against it.`;
|
|
};
|
|
}
|
|
|
|
/** Joins mid-run notices from several sources into one follow-up, or null when none has news. */
|
|
export function combineMidRunPolls(...polls: Array<() => string | null>): () => string | null {
|
|
return () => {
|
|
const notices = polls.map((poll) => poll()).filter((notice): notice is string => notice !== null);
|
|
return notices.length > 0 ? notices.join("\n\n") : null;
|
|
};
|
|
}
|