File size: 2,468 Bytes
1dbc34b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import { useEffect } from 'react';
import { useAppStore } from '@/store/app-store';
import { getHttpApiClient } from '@/lib/http-api-client';
import { pathsEqual } from '@/lib/utils';

interface InitScriptStartedPayload {
  projectPath: string;
  worktreePath: string;
  branch: string;
}

interface InitScriptOutputPayload {
  projectPath: string;
  branch: string;
  type: 'stdout' | 'stderr';
  content: string;
}

interface InitScriptCompletedPayload {
  projectPath: string;
  worktreePath: string;
  branch: string;
  success: boolean;
  exitCode?: number;
  error?: string;
}

/**
 * Hook to subscribe to init script WebSocket events and update the store.
 * Should be used in a component that's always mounted (e.g., board-view).
 */
export function useInitScriptEvents(projectPath: string | null) {
  const setInitScriptState = useAppStore((s) => s.setInitScriptState);
  const appendInitScriptOutput = useAppStore((s) => s.appendInitScriptOutput);

  useEffect(() => {
    if (!projectPath) return;

    const api = getHttpApiClient();

    const unsubscribe = api.worktree.onInitScriptEvent((event) => {
      const payload = event.payload as
        | InitScriptStartedPayload
        | InitScriptOutputPayload
        | InitScriptCompletedPayload;

      // Only handle events for the current project (use pathsEqual for cross-platform path comparison)
      if (!pathsEqual(payload.projectPath, projectPath)) return;

      switch (event.type) {
        case 'worktree:init-started': {
          const startPayload = payload as InitScriptStartedPayload;
          setInitScriptState(projectPath, startPayload.branch, {
            status: 'running',
            branch: startPayload.branch,
            output: [],
            error: undefined,
          });
          break;
        }
        case 'worktree:init-output': {
          const outputPayload = payload as InitScriptOutputPayload;
          appendInitScriptOutput(projectPath, outputPayload.branch, outputPayload.content);
          break;
        }
        case 'worktree:init-completed': {
          const completePayload = payload as InitScriptCompletedPayload;
          setInitScriptState(projectPath, completePayload.branch, {
            status: completePayload.success ? 'success' : 'failed',
            error: completePayload.error,
          });
          break;
        }
      }
    });

    return unsubscribe;
  }, [projectPath, setInitScriptState, appendInitScriptOutput]);
}