Improve auto-loop event emission and add ntfy notifications (#821)

This commit is contained in:
gsxdsm
2026-03-01 00:12:22 -08:00
committed by GitHub
parent 63b0a4fb38
commit 57bcb2802d
53 changed files with 4620 additions and 255 deletions

View File

@@ -248,7 +248,7 @@ export function useWorktreeBranches(worktreePath: string | undefined, includeRem
isGitRepo: true,
hasCommits: true,
trackingRemote: result.result?.trackingRemote,
remotesWithBranch: result.result?.remotesWithBranch,
remotesWithBranch: (result.result as { remotesWithBranch?: string[] })?.remotesWithBranch,
};
},
enabled: !!worktreePath,

View File

@@ -30,7 +30,7 @@ export function useAgentOutputWebSocket({
onFeatureComplete,
}: UseAgentOutputWebSocketProps) {
const [streamedContent, setStreamedContent] = useState('');
const closeTimeoutRef = useRef<NodeJS.Timeout>();
const closeTimeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
// Use React Query for initial output loading
const { data: initialOutput = '', isLoading } = useAgentOutput(projectPath, featureId, {
@@ -98,7 +98,16 @@ export function useAgentOutputWebSocket({
if (isBacklogPlan) {
// Handle backlog plan events
if (api.backlogPlan) {
unsubscribe = api.backlogPlan.onEvent(handleBacklogPlanEvent);
unsubscribe = api.backlogPlan.onEvent((data: unknown) => {
if (
data !== null &&
typeof data === 'object' &&
'type' in data &&
typeof (data as { type: unknown }).type === 'string'
) {
handleBacklogPlanEvent(data as BacklogPlanEvent);
}
});
}
} else {
// Handle auto mode events

View File

@@ -39,6 +39,7 @@ import {
migratePhaseModelEntry,
type GlobalSettings,
type CursorModelId,
type PhaseModelEntry,
} from '@automaker/types';
const logger = createLogger('SettingsMigration');
@@ -198,6 +199,8 @@ export function parseLocalStorageSettings(): Partial<GlobalSettings> | null {
mcpServers: state.mcpServers as GlobalSettings['mcpServers'],
promptCustomization: state.promptCustomization as GlobalSettings['promptCustomization'],
eventHooks: state.eventHooks as GlobalSettings['eventHooks'],
ntfyEndpoints: state.ntfyEndpoints as GlobalSettings['ntfyEndpoints'],
featureTemplates: state.featureTemplates as GlobalSettings['featureTemplates'],
projects: state.projects as GlobalSettings['projects'],
trashedProjects: state.trashedProjects as GlobalSettings['trashedProjects'],
currentProjectId: (state.currentProject as { id?: string } | null)?.id ?? null,
@@ -809,6 +812,8 @@ export function hydrateStoreFromSettings(settings: GlobalSettings): void {
mcpServers: settings.mcpServers ?? [],
promptCustomization: settings.promptCustomization ?? {},
eventHooks: settings.eventHooks ?? [],
ntfyEndpoints: settings.ntfyEndpoints ?? [],
featureTemplates: settings.featureTemplates ?? [],
claudeCompatibleProviders: settings.claudeCompatibleProviders ?? [],
claudeApiProfiles: settings.claudeApiProfiles ?? [],
activeClaudeApiProfileId: settings.activeClaudeApiProfileId ?? null,
@@ -821,7 +826,10 @@ export function hydrateStoreFromSettings(settings: GlobalSettings): void {
agentModelBySession: settings.agentModelBySession
? Object.fromEntries(
Object.entries(settings.agentModelBySession as Record<string, unknown>).map(
([sessionId, entry]) => [sessionId, migratePhaseModelEntry(entry)]
([sessionId, entry]) => [
sessionId,
migratePhaseModelEntry(entry as string | PhaseModelEntry | null | undefined),
]
)
)
: current.agentModelBySession,
@@ -945,6 +953,8 @@ function buildSettingsUpdateFromStore(): Record<string, unknown> {
mcpServers: state.mcpServers,
promptCustomization: state.promptCustomization,
eventHooks: state.eventHooks,
ntfyEndpoints: state.ntfyEndpoints,
featureTemplates: state.featureTemplates,
claudeCompatibleProviders: state.claudeCompatibleProviders,
claudeApiProfiles: state.claudeApiProfiles,
activeClaudeApiProfileId: state.activeClaudeApiProfileId,

View File

@@ -37,6 +37,7 @@ import {
type CursorModelId,
type GeminiModelId,
type CopilotModelId,
type PhaseModelEntry,
} from '@automaker/types';
const logger = createLogger('SettingsSync');
@@ -106,6 +107,7 @@ const SETTINGS_FIELDS_TO_SYNC = [
'subagentsSources',
'promptCustomization',
'eventHooks',
'ntfyEndpoints',
'featureTemplates',
'claudeCompatibleProviders', // Claude-compatible provider configs - must persist to server
'claudeApiProfiles',
@@ -855,7 +857,10 @@ export async function refreshSettingsFromServer(): Promise<boolean> {
agentModelBySession: serverSettings.agentModelBySession
? Object.fromEntries(
Object.entries(serverSettings.agentModelBySession as Record<string, unknown>).map(
([sessionId, entry]) => [sessionId, migratePhaseModelEntry(entry)]
([sessionId, entry]) => [
sessionId,
migratePhaseModelEntry(entry as string | PhaseModelEntry | null | undefined),
]
)
)
: currentAppState.agentModelBySession,
@@ -870,6 +875,8 @@ export async function refreshSettingsFromServer(): Promise<boolean> {
recentFolders: serverSettings.recentFolders ?? [],
// Event hooks
eventHooks: serverSettings.eventHooks ?? [],
// Ntfy endpoints
ntfyEndpoints: serverSettings.ntfyEndpoints ?? [],
// Feature templates
featureTemplates: serverSettings.featureTemplates ?? [],
// Codex CLI Settings