• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

apowers313 / aiforge / 20962792399

13 Jan 2026 03:39PM UTC coverage: 84.707%. First build
20962792399

push

github

apowers313
feat: initial commit

787 of 905 branches covered (86.96%)

Branch coverage included in aggregate %.

4248 of 5039 new or added lines in 70 files covered. (84.3%)

4248 of 5039 relevant lines covered (84.3%)

13.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.55
/src/server/storage/stores/ShellStore.ts
1
/**
2
 * Shell storage - manages shell data persistence
3
 */
4
import { JsonStore } from '../JsonStore.js';
1✔
5
import type { Shell } from '@shared/types/index.js';
6

7
interface ShellData {
8
  version: number;
9
  shells: Shell[];
10
  shellCounter: number;
11
}
12

13
export class ShellStore {
1✔
14
  private store: JsonStore<ShellData>;
17✔
15

16
  constructor(filePath: string) {
17✔
17
    this.store = new JsonStore<ShellData>({
17✔
18
      filePath,
17✔
19
      defaultValue: { version: 1, shells: [], shellCounter: 0 },
17✔
20
    });
17✔
21
  }
17✔
22

23
  async getAll(): Promise<Shell[]> {
17✔
NEW
24
    const data = await this.store.read();
×
NEW
25
    return data.shells;
×
NEW
26
  }
×
27

28
  async getById(id: string): Promise<Shell | null> {
17✔
29
    const data = await this.store.read();
3✔
30
    return data.shells.find((s) => s.id === id) ?? null;
3✔
31
  }
3✔
32

33
  async getByProjectId(projectId: string): Promise<Shell[]> {
17✔
34
    const data = await this.store.read();
1✔
35
    return data.shells.filter((s) => s.projectId === projectId);
1✔
36
  }
1✔
37

38
  async create(shell: Shell): Promise<void> {
17✔
39
    await this.store.update((data) => ({
7✔
40
      ...data,
7✔
41
      shells: [...data.shells, shell],
7✔
42
    }));
7✔
43
  }
7✔
44

45
  async getNextShellNumber(): Promise<number> {
17✔
46
    let counter = 0;
1✔
47
    await this.store.update((data) => {
1✔
48
      counter = data.shellCounter + 1;
1✔
49
      return {
1✔
50
        ...data,
1✔
51
        shellCounter: counter,
1✔
52
      };
1✔
53
    });
1✔
54
    return counter;
1✔
55
  }
1✔
56

57
  async update(id: string, updates: Partial<Pick<Shell, 'name' | 'status' | 'pid' | 'cwd'>>): Promise<Shell | null> {
17✔
58
    let updatedShell: Shell | null = null;
2✔
59

60
    await this.store.update((data) => {
2✔
61
      const index = data.shells.findIndex((s) => s.id === id);
2✔
62
      if (index === -1) {
2✔
63
        return data;
1✔
64
      }
1✔
65

66
      const shell = data.shells[index];
1✔
67
      if (!shell) {
2!
NEW
68
        return data;
×
NEW
69
      }
✔
70

71
      updatedShell = {
1✔
72
        ...shell,
1✔
73
        ...updates,
1✔
74
        updatedAt: new Date().toISOString(),
1✔
75
      };
1✔
76

77
      const newShells = [...data.shells];
1✔
78
      newShells[index] = updatedShell;
1✔
79

80
      return {
1✔
81
        ...data,
1✔
82
        shells: newShells,
1✔
83
      };
1✔
84
    });
2✔
85

86
    return updatedShell;
2✔
87
  }
2✔
88

89
  async delete(id: string): Promise<boolean> {
17✔
90
    let deleted = false;
2✔
91

92
    await this.store.update((data) => {
2✔
93
      const newShells = data.shells.filter((s) => s.id !== id);
2✔
94
      deleted = newShells.length < data.shells.length;
2✔
95
      return {
2✔
96
        ...data,
2✔
97
        shells: newShells,
2✔
98
      };
2✔
99
    });
2✔
100

101
    return deleted;
2✔
102
  }
2✔
103

104
  async deleteByProjectId(projectId: string): Promise<number> {
17✔
105
    let deletedCount = 0;
2✔
106

107
    await this.store.update((data) => {
2✔
108
      const newShells = data.shells.filter((s) => s.projectId !== projectId);
2✔
109
      deletedCount = data.shells.length - newShells.length;
2✔
110
      return {
2✔
111
        ...data,
2✔
112
        shells: newShells,
2✔
113
      };
2✔
114
    });
2✔
115

116
    return deletedCount;
2✔
117
  }
2✔
118
}
17✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc