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

apowers313 / aiforge / 21570337701

01 Feb 2026 09:11PM UTC coverage: 81.026% (-2.9%) from 83.954%
21570337701

push

github

apowers313
test: increase coverage to 80%+

2049 of 2382 branches covered (86.02%)

Branch coverage included in aggregate %.

1849 of 2529 new or added lines in 25 files covered. (73.11%)

681 existing lines in 21 files now uncovered.

9861 of 12317 relevant lines covered (80.06%)

26.33 hits per line

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

56.57
/src/client/components/worktrees/AddWorktreeModal.tsx
1
import { useState } from 'react';
1✔
2
import { Modal, TextInput, Button, Group, Stack, Text } from '@mantine/core';
1✔
3
import { useCreateWorktree, useMainBranch } from '@client/hooks/useWorktrees';
1✔
4

5
interface AddWorktreeModalProps {
6
  projectId: string;
7
  opened: boolean;
8
  onClose: () => void;
9
}
10

11
export function AddWorktreeModal({
1✔
12
  projectId,
74✔
13
  opened,
74✔
14
  onClose,
74✔
15
}: AddWorktreeModalProps): React.ReactElement {
74✔
16
  const [name, setName] = useState('');
74✔
17
  const [baseBranch, setBaseBranch] = useState('');
74✔
18
  const [error, setError] = useState<string | null>(null);
74✔
19

20
  const { data: mainBranch } = useMainBranch(projectId);
74✔
21
  const createWorktree = useCreateWorktree(projectId);
74✔
22

23
  const handleClose = (): void => {
74✔
NEW
24
    setName('');
×
NEW
25
    setBaseBranch('');
×
NEW
26
    setError(null);
×
NEW
27
    onClose();
×
NEW
28
  };
×
29

30
  const handleSubmit = async (): Promise<void> => {
74✔
NEW
31
    if (!name.trim()) {
×
NEW
32
      setError('Worktree name is required');
×
NEW
33
      return;
×
NEW
34
    }
×
35

36
    // Validate branch name format
NEW
37
    const branchNameRegex = /^[a-zA-Z0-9][a-zA-Z0-9._/-]*$/;
×
NEW
38
    if (!branchNameRegex.test(name.trim())) {
×
NEW
39
      setError(
×
NEW
40
        'Invalid branch name: must start with alphanumeric and contain only alphanumeric, dots, underscores, hyphens, and forward slashes',
×
NEW
41
      );
×
NEW
42
      return;
×
NEW
43
    }
×
44

NEW
45
    setError(null);
×
46

NEW
47
    try {
×
NEW
48
      await createWorktree.mutateAsync({
×
NEW
49
        name: name.trim(),
×
NEW
50
        baseBranch: baseBranch.trim() || undefined,
×
NEW
51
      });
×
NEW
52
      handleClose();
×
NEW
53
    } catch (err) {
×
NEW
54
      if (err instanceof Error) {
×
NEW
55
        setError(err.message);
×
NEW
56
      } else {
×
NEW
57
        setError('Failed to create worktree');
×
NEW
58
      }
×
NEW
59
    }
×
NEW
60
  };
×
61

62
  const isCreateDisabled = !name.trim() || createWorktree.isPending;
74!
63

64
  return (
74✔
65
    <Modal
74✔
66
      opened={opened}
74✔
67
      onClose={handleClose}
74✔
68
      title="Add Worktree"
74✔
69
      centered
74✔
70
    >
71
      <Stack gap="md">
74✔
72
        <TextInput
74✔
73
          label="Worktree name"
74✔
74
          description="This will be used as the branch name"
74✔
75
          placeholder="feature/my-feature"
74✔
76
          value={name}
74✔
77
          onChange={(e) => {
74✔
NEW
78
            setName(e.target.value);
×
NEW
79
            setError(null);
×
NEW
80
          }}
×
81
          error={error}
74✔
82
          data-autofocus
74✔
83
        />
74✔
84

85
        <TextInput
74✔
86
          label="Base branch (optional)"
74✔
87
          description={`Defaults to ${mainBranch ?? 'main'}`}
74✔
88
          placeholder={mainBranch ?? 'main'}
74✔
89
          value={baseBranch}
74✔
90
          onChange={(e) => {
74✔
NEW
91
            setBaseBranch(e.target.value);
×
NEW
92
          }}
×
93
        />
74✔
94

95
        {error && (
74!
NEW
96
          <Text c="red" size="sm">
×
NEW
97
            {error}
×
NEW
98
          </Text>
×
99
        )}
100

101
        <Group justify="flex-end" mt="md">
74✔
102
          <Button variant="subtle" onClick={handleClose}>
74✔
103
            Cancel
104
          </Button>
74✔
105
          <Button
74✔
106
            onClick={() => {
74✔
NEW
107
              void handleSubmit();
×
NEW
108
            }}
×
109
            disabled={isCreateDisabled}
74✔
110
            loading={createWorktree.isPending}
74✔
111
          >
74✔
112
            Create
113
          </Button>
74✔
114
        </Group>
74✔
115
      </Stack>
74✔
116
    </Modal>
74✔
117
  );
118
}
74✔
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