writer.ts
1175 bytes
1import type { FileSystem } from "../ports/fs.ts";
2import type { ApplyResult, SkillChange } from "../types.ts";
3
4export interface SkillChangeWriter {
5 apply(changes: SkillChange[]): Promise<ApplyResult>;
6}
7
8export class AtomicSkillChangeWriter implements SkillChangeWriter {
9 constructor(private readonly fs: FileSystem) {}
10
11 async apply(changes: SkillChange[]): Promise<ApplyResult> {
12 const result: ApplyResult = { applied: [], skipped: [], errors: [] };
13
14 for (const change of changes) {
15 try {
16 const current = await this.fs.readFile(change.filePath);
17 if (current !== change.patch.oldText) {
18 result.errors.push({
19 skill: change.skill,
20 message: `${change.skill.name}: file changed while dialog was open; skipped`,
21 });
22 continue;
23 }
24 await this.fs.writeFileAtomic(change.filePath, change.patch.newText);
25 result.applied.push(change);
26 } catch (error) {
27 result.errors.push({
28 skill: change.skill,
29 message: `${change.skill.name}: ${error instanceof Error ? error.message : String(error)}`,
30 });
31 }
32 }
33
34 return result;
35 }
36}