Files
makelore/src/lib/coding-projects.ts

139 lines
4.4 KiB
TypeScript

import { hostApiFetch } from './host-api';
import type {
CodingConversationMetadata,
CodingProjectConfigSnapshot,
CodingProjectSummary,
} from '@/types/coding-project';
import type { ProjectType } from '../../shared/project-config';
import type { ProjectIdentityChoice } from '../../shared/coding-project-contracts';
const CANONICAL_PROJECT_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/u;
export function isCanonicalCodingProjectId(value: string): boolean {
return CANONICAL_PROJECT_ID_PATTERN.test(value.trim());
}
export interface CodingProjectCatalog {
projects: CodingProjectSummary[];
activeProjectId: string | null;
}
export async function listCodingProjects(): Promise<CodingProjectCatalog> {
return await hostApiFetch<CodingProjectCatalog>('/api/coding/projects');
}
export async function openCodingProject(projectPath: string): Promise<CodingProjectSummary> {
const response = await hostApiFetch<{ project: CodingProjectSummary }>('/api/coding/projects/open', {
method: 'POST',
body: JSON.stringify({ projectPath }),
});
return response.project;
}
export async function createCodingProject(input: {
projectPath?: string;
parentPath?: string;
projectName?: string;
projectType?: ProjectType;
identity: ProjectIdentityChoice;
}): Promise<CodingProjectConfigSnapshot> {
const response = await hostApiFetch<{ snapshot: CodingProjectConfigSnapshot }>('/api/coding/projects/create', {
method: 'POST',
body: JSON.stringify(input),
});
return response.snapshot;
}
export async function resolveCodingProjectIdentity(
localProjectId: string,
identity: ProjectIdentityChoice,
): Promise<CodingProjectConfigSnapshot> {
const response = await hostApiFetch<{ snapshot: CodingProjectConfigSnapshot }>(
'/api/coding/projects/identity',
{
method: 'POST',
body: JSON.stringify({ localProjectId, identity }),
},
);
return response.snapshot;
}
export async function makeCodingProjectIndependentCopy(
localProjectId: string,
): Promise<CodingProjectConfigSnapshot> {
const response = await hostApiFetch<{ snapshot: CodingProjectConfigSnapshot }>(
'/api/coding/projects/identity/independent-copy',
{
method: 'POST',
body: JSON.stringify({ localProjectId, confirmed: true }),
},
);
return response.snapshot;
}
export async function setActiveCodingProject(projectId: string): Promise<CodingProjectSummary> {
const response = await hostApiFetch<{ project: CodingProjectSummary }>('/api/coding/projects/active', {
method: 'POST',
body: JSON.stringify({ projectId }),
});
return response.project;
}
export async function removeCodingProject(projectId: string): Promise<void> {
await hostApiFetch('/api/coding/projects/remove', {
method: 'POST',
body: JSON.stringify({ projectId }),
});
}
export async function getCodingProjectConfig(
projectId: string,
): Promise<CodingProjectConfigSnapshot> {
const response = await hostApiFetch<{ snapshot: CodingProjectConfigSnapshot }>(
`/api/coding/projects/config?projectId=${encodeURIComponent(projectId)}`,
);
return response.snapshot;
}
export async function listCodingProjectConversations(
projectId: string,
): Promise<CodingConversationMetadata[]> {
const response = await hostApiFetch<{ conversations: CodingConversationMetadata[] }>(
`/api/coding/projects/conversations?projectId=${encodeURIComponent(projectId)}`,
);
return response.conversations;
}
export async function createCodingProjectConversation(input: {
projectId: string;
agentId: string;
title: string;
}): Promise<CodingConversationMetadata> {
const response = await hostApiFetch<{ conversation: CodingConversationMetadata }>(
'/api/coding/projects/conversations',
{
method: 'POST',
body: JSON.stringify(input),
},
);
return response.conversation;
}
export async function patchCodingProjectConversation(
conversationId: string,
patch: { title?: string; archived?: boolean; unread?: boolean },
): Promise<CodingConversationMetadata> {
const response = await hostApiFetch<{ conversation: CodingConversationMetadata }>(
`/api/coding/conversations/${encodeURIComponent(conversationId)}`,
{ method: 'PATCH', body: JSON.stringify(patch) },
);
return response.conversation;
}
export async function deleteCodingProjectConversation(conversationId: string): Promise<void> {
await hostApiFetch(
`/api/coding/conversations/${encodeURIComponent(conversationId)}`,
{ method: 'DELETE' },
);
}