mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-30 06:12:03 +00:00
Fix type mismatch in loadBacklogPlan where secureFs.readFile with 'utf-8' encoding returns union type string | Buffer, causing JSON.parse to fail type checking. Cast raw to string to satisfy TypeScript strict mode. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
115 lines
2.8 KiB
TypeScript
115 lines
2.8 KiB
TypeScript
/**
|
|
* Common utilities for backlog plan routes
|
|
*/
|
|
|
|
import { createLogger } from '@automaker/utils';
|
|
import { ensureAutomakerDir, getAutomakerDir } from '@automaker/platform';
|
|
import * as secureFs from '../../lib/secure-fs.js';
|
|
import path from 'path';
|
|
import type { BacklogPlanResult } from '@automaker/types';
|
|
|
|
const logger = createLogger('BacklogPlan');
|
|
|
|
// State for tracking running generation
|
|
let isRunning = false;
|
|
let currentAbortController: AbortController | null = null;
|
|
let runningDetails: {
|
|
projectPath: string;
|
|
prompt: string;
|
|
model?: string;
|
|
startedAt: string;
|
|
} | null = null;
|
|
|
|
const BACKLOG_PLAN_FILENAME = 'backlog-plan.json';
|
|
|
|
export interface StoredBacklogPlan {
|
|
savedAt: string;
|
|
prompt: string;
|
|
model?: string;
|
|
result: BacklogPlanResult;
|
|
}
|
|
|
|
export function getBacklogPlanStatus(): { isRunning: boolean } {
|
|
return { isRunning };
|
|
}
|
|
|
|
export function setRunningState(running: boolean, abortController?: AbortController | null): void {
|
|
isRunning = running;
|
|
if (!running) {
|
|
runningDetails = null;
|
|
}
|
|
if (abortController !== undefined) {
|
|
currentAbortController = abortController;
|
|
}
|
|
}
|
|
|
|
export function setRunningDetails(
|
|
details: {
|
|
projectPath: string;
|
|
prompt: string;
|
|
model?: string;
|
|
startedAt: string;
|
|
} | null
|
|
): void {
|
|
runningDetails = details;
|
|
}
|
|
|
|
export function getRunningDetails(): {
|
|
projectPath: string;
|
|
prompt: string;
|
|
model?: string;
|
|
startedAt: string;
|
|
} | null {
|
|
return runningDetails;
|
|
}
|
|
|
|
function getBacklogPlanPath(projectPath: string): string {
|
|
return path.join(getAutomakerDir(projectPath), BACKLOG_PLAN_FILENAME);
|
|
}
|
|
|
|
export async function saveBacklogPlan(projectPath: string, plan: StoredBacklogPlan): Promise<void> {
|
|
await ensureAutomakerDir(projectPath);
|
|
const filePath = getBacklogPlanPath(projectPath);
|
|
await secureFs.writeFile(filePath, JSON.stringify(plan, null, 2), 'utf-8');
|
|
}
|
|
|
|
export async function loadBacklogPlan(projectPath: string): Promise<StoredBacklogPlan | null> {
|
|
try {
|
|
const filePath = getBacklogPlanPath(projectPath);
|
|
const raw = await secureFs.readFile(filePath, 'utf-8');
|
|
const parsed = JSON.parse(raw as string) as StoredBacklogPlan;
|
|
if (!parsed?.result?.changes) {
|
|
return null;
|
|
}
|
|
return parsed;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function clearBacklogPlan(projectPath: string): Promise<void> {
|
|
try {
|
|
const filePath = getBacklogPlanPath(projectPath);
|
|
await secureFs.unlink(filePath);
|
|
} catch {
|
|
// ignore missing file
|
|
}
|
|
}
|
|
|
|
export function getAbortController(): AbortController | null {
|
|
return currentAbortController;
|
|
}
|
|
|
|
export function getErrorMessage(error: unknown): string {
|
|
if (error instanceof Error) {
|
|
return error.message;
|
|
}
|
|
return String(error);
|
|
}
|
|
|
|
export function logError(error: unknown, context: string): void {
|
|
logger.error(`[BacklogPlan] ${context}:`, getErrorMessage(error));
|
|
}
|
|
|
|
export { logger };
|