@pimzino/spec-workflow-mcp
Version:
MCP server for spec-driven development workflow with real-time web dashboard
98 lines • 3.59 kB
JavaScript
import { promises as fs } from 'fs';
import { PathUtils } from './path-utils.js';
export class SpecArchiveService {
projectPath;
constructor(projectPath) {
this.projectPath = projectPath;
}
async archiveSpec(specName) {
const activeSpecPath = PathUtils.getSpecPath(this.projectPath, specName);
const archiveSpecPath = PathUtils.getArchiveSpecPath(this.projectPath, specName);
// Verify the active spec exists
try {
await fs.access(activeSpecPath);
}
catch {
throw new Error(`Spec '${specName}' not found in active specs`);
}
// Verify the archive destination doesn't already exist
try {
await fs.access(archiveSpecPath);
throw new Error(`Spec '${specName}' already exists in archive`);
}
catch (error) {
if (error instanceof Error && error.code !== 'ENOENT') {
throw error;
}
}
try {
// Ensure archive directory structure exists
await fs.mkdir(PathUtils.getArchiveSpecsPath(this.projectPath), { recursive: true });
// Move the entire spec directory to archive
await fs.rename(activeSpecPath, archiveSpecPath);
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(`Failed to archive spec '${specName}': ${errorMessage}`);
}
}
async unarchiveSpec(specName) {
const archiveSpecPath = PathUtils.getArchiveSpecPath(this.projectPath, specName);
const activeSpecPath = PathUtils.getSpecPath(this.projectPath, specName);
// Verify the archived spec exists
try {
await fs.access(archiveSpecPath);
}
catch {
throw new Error(`Spec '${specName}' not found in archive`);
}
// Verify the active destination doesn't already exist
try {
await fs.access(activeSpecPath);
throw new Error(`Spec '${specName}' already exists in active specs`);
}
catch (error) {
if (error instanceof Error && error.code !== 'ENOENT') {
throw error;
}
}
try {
// Ensure active specs directory exists
await fs.mkdir(PathUtils.getSpecPath(this.projectPath, ''), { recursive: true });
// Move the entire spec directory back to active
await fs.rename(archiveSpecPath, activeSpecPath);
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(`Failed to unarchive spec '${specName}': ${errorMessage}`);
}
}
async isSpecActive(specName) {
try {
await fs.access(PathUtils.getSpecPath(this.projectPath, specName));
return true;
}
catch {
return false;
}
}
async isSpecArchived(specName) {
try {
await fs.access(PathUtils.getArchiveSpecPath(this.projectPath, specName));
return true;
}
catch {
return false;
}
}
async getSpecLocation(specName) {
const isActive = await this.isSpecActive(specName);
if (isActive)
return 'active';
const isArchived = await this.isSpecArchived(specName);
if (isArchived)
return 'archived';
return 'not-found';
}
}
//# sourceMappingURL=archive-service.js.map