UNPKG

@phren/cli

Version:

Knowledge layer for AI agents - CLI, MCP server, and data layer

159 lines (158 loc) • 8.5 kB
import { type PhrenResult } from "../shared.js"; import { type AddFindingResult } from "../shared/content.js"; import { type FindingCitation } from "../content/citation.js"; import { type FindingLifecycleStatus } from "../finding/lifecycle.js"; export type { TaskSection, TaskItem, TaskDoc } from "./tasks.js"; export { readTasks, readTasksAcrossProjects, resolveTaskItem, addTask, addTasks, completeTasks, completeTask, removeTask, removeTasks, updateTask, linkTaskIssue, pinTask, unpinTask, workNextTask, tidyDoneTasks, taskMarkdown, appendChildFinding, promoteTask, TASKS_FILENAME, TASK_FILE_ALIASES, canonicalTaskFilePath, resolveTaskFilePath, isTaskFileName, type AddTaskOptions, } from "./tasks.js"; export { addProjectToProfile, listMachines, listProfiles, listProjectCards, removeProjectFromProfile, setMachineProfile, type ProfileInfo, type ProjectCard, } from "../profile-store.js"; export { loadShellState, resetShellState, saveShellState, type ShellState, } from "../shell/state-store.js"; export { getRuntimeHealth as readRuntimeHealth } from "../shared/governance.js"; export { FINDINGS_FILENAME } from "../filenames.js"; export interface FindingItem { id: string; /** Stable 8-char hex ID embedded as `<!-- fid:XXXXXXXX -->`. Survives reordering and consolidation. */ stableId?: string; date: string; text: string; citation?: string; citationData?: FindingCitation; taskItem?: string; confidence?: number; scope?: string; /** Machine hostname where this finding was originally recorded. */ machine?: string; /** Actor (username) who recorded this finding. */ actor?: string; /** First 60 chars of the newer finding that supersedes this one. Set when this finding is stale. */ supersededBy?: string; /** First 60 chars of the older finding this one replaces. */ supersedes?: string; /** Snippets of findings this one contradicts. */ contradicts?: string[]; status: FindingLifecycleStatus; status_updated?: string; status_reason?: string; status_ref?: string; /** Indicates whether this item comes from archived history blocks (<details> / phren:archive). */ archived?: boolean; /** Tier marker used to distinguish current truth vs archived history. */ tier?: "current" | "archived"; } export interface ReadFindingsOptions { includeArchived?: boolean; } export interface FindingHistoryEntry { id: string; stableId?: string; text: string; timeline: FindingItem[]; current?: FindingItem; archivedCount: number; } export interface QueueItem { id: string; section: "Review" | "Stale" | "Conflicts"; date: string; text: string; line: string; confidence?: number; risky: boolean; machine?: string; model?: string; } export interface ProjectQueueItem extends QueueItem { project: string; } export declare function readFindings(phrenPath: string, project: string, opts?: ReadFindingsOptions): PhrenResult<FindingItem[]>; /** * Parse FINDINGS.md-shaped content into findings. Shared by `readFindings` * (the project's FINDINGS.md) and the memory link's scan of archived topic * files under `reference/topics/`, which use the same bullet + citation shape. */ export declare function parseFindingsContent(content: string, opts?: ReadFindingsOptions): FindingItem[]; export declare function readFindingHistory(phrenPath: string, project: string, findingId?: string): PhrenResult<FindingHistoryEntry[]>; export declare function addFinding(phrenPath: string, project: string, learning: string): PhrenResult<AddFindingResult>; /** * `exactOnly` accepts only a fid or the whole normalized text (a type tag aside): a caller that * holds a finding's full text (review-queue reject) must never delete a * different finding that merely contains it. */ export declare function removeFinding(phrenPath: string, project: string, match: string, opts?: { exactOnly?: boolean; }): PhrenResult<string>; export declare function removeFindings(phrenPath: string, project: string, matches: string[]): PhrenResult<{ removed: string[]; errors: string[]; }>; export declare function editFinding(phrenPath: string, project: string, oldText: string, newText: string): PhrenResult<string>; export declare function readReviewQueue(phrenPath: string, project: string): PhrenResult<QueueItem[]>; export type QueueApproveOutcome = "promoted" | "already_present" | "already_archived"; export interface QueueApproveResult { outcome: QueueApproveOutcome; message: string; /** Canonical finding text the verb acted on (confidence marker stripped, type tag kept). */ text: string; } export type QueueRejectOutcome = /** Removed from the live FINDINGS.md tier. */ "removed" /** Removed from reference/topics/*.md, where auto-archive had moved it. */ | "removed_from_archive" /** Nothing to remove: the candidate was never written anywhere. Dequeuing *is* the rejection. */ | "discarded"; export interface QueueRejectResult { outcome: QueueRejectOutcome; message: string; text: string; } /** * Approve a queue item: make it real, then dequeue. * * Three outcomes, because a queue line can point at three different realities: * * - `promoted` — the text is not in FINDINGS.md, so approving *writes* it. This is the * case for every extraction candidate that scored below `autoAcceptThreshold`: * extraction queues those without ever adding them, so the old "just splice the line * out" behaviour silently discarded them. Promotion goes through `addFindingToFile`, * the same path a direct add uses, so dedup, fid assignment, citation metadata, and * the findings-cap auto-archive all behave identically. * - `already_present` — the text is already a live finding (govern queues existing * findings for Stale/Conflicts review). Approving means "keep it"; just dequeue. * - `already_archived` — the content only exists in `reference/topics/`, because * auto-archive moved it after it was queued. It is still live for retrieval, so the * archive is left untouched and the item is dequeued. */ export declare function approveQueueItemDetailed(phrenPath: string, project: string, lineText: string): PhrenResult<QueueApproveResult>; /** Remove a queue item's line from review.md, promoting it to a finding when needed. */ export declare function approveQueueItem(phrenPath: string, project: string, lineText: string): PhrenResult<string>; /** * Reject a queue item: destroy the content wherever it actually lives, then dequeue. * * Rejection removes from the live FINDINGS.md tier *and* from `reference/topics/*.md`, * because auto-archive moves findings there without reconciling their queue lines and * archived content is still injected into agent prompts. Leaving it would make reject a * lie — the hosts tell users rejection removes the finding permanently. * * Two situations deliberately do NOT succeed quietly: * - the content sits in a FINDINGS.md archive block (`<details>` / `phren:archive`), * which the rest of the codebase treats as read-only history; and * - several *different* bullets match, so deleting one would be a guess. * * Both return an error and leave the queue line in place, so the user sees the problem * instead of a success message over undeleted content. */ export declare function rejectQueueItemDetailed(phrenPath: string, project: string, lineText: string): PhrenResult<QueueRejectResult>; /** Remove a queue item from review.md AND the corresponding finding wherever it lives. */ export declare function rejectQueueItem(phrenPath: string, project: string, lineText: string): PhrenResult<string>; /** * Drop a queue line and nothing else. * * Unlike `rejectQueueItem`, this never touches FINDINGS.md or `reference/topics/`. * It is the verb for "stop asking me about this", not "this is wrong" — which is * what automated expiry needs: a governance-queued finding that already lives in * FINDINGS.md must survive its queue line timing out. */ export declare function dequeueQueueItem(phrenPath: string, project: string, lineText: string): PhrenResult<string>; /** Edit a queue item's text in review.md and the corresponding finding in FINDINGS.md. */ export declare function editQueueItem(phrenPath: string, project: string, lineText: string, newText: string): PhrenResult<string>; export declare function readReviewQueueAcrossProjects(phrenPath: string, profile?: string): PhrenResult<ProjectQueueItem[]>;