feat: add DDD scan, sync, and update commands for document indexing

- Implemented `/ddd:scan` command to analyze existing codebases and generate document indices without specifications. This includes phases for project structure analysis, component discovery, feature inference, and requirement extraction.
- Introduced `/ddd:sync` command for post-task synchronization, updating document indices, generating action logs, and refreshing feature/component documentation after development tasks.
- Added `/ddd:update` command for lightweight incremental updates to the document index, allowing for quick impact checks during development and pre-commit validation.
- Created `execute.md` for the coordinator role in the team lifecycle, detailing the spawning of executor team-workers for IMPL tasks.
- Added `useHasHydrated` hook to determine if the Zustand workflow store has been rehydrated from localStorage, improving state management reliability.
This commit is contained in:
catlog22
2026-03-07 00:00:18 +08:00
parent a9469a5e3b
commit 7ee9b579fa
18 changed files with 2739 additions and 155 deletions

View File

@@ -0,0 +1,55 @@
// ========================================
// useHasHydrated Hook
// ========================================
// Determines if the Zustand workflow store has been rehydrated from localStorage
// Uses Zustand persist middleware's onFinishHydration callback for reliable detection
import { useState, useEffect } from 'react';
import { useWorkflowStore } from '@/stores/workflowStore';
/**
* A hook to determine if the Zustand workflow store has been rehydrated.
* Returns `true` once the persisted state has been loaded from localStorage.
*
* This hook uses the Zustand persist middleware's onFinishHydration callback
* instead of relying on internal state management, which avoids circular
* reference issues during store initialization.
*
* @example
* ```tsx
* function MyComponent() {
* const hasHydrated = useHasHydrated();
*
* useEffect(() => {
* if (!hasHydrated) return;
* // Safe to access persisted store values here
* }, [hasHydrated]);
*
* if (!hasHydrated) return <LoadingSpinner />;
* return <Content />;
* }
* ```
*/
export function useHasHydrated(): boolean {
const [hydrated, setHydrated] = useState(() => {
// Check initial hydration status synchronously
return useWorkflowStore.persist.hasHydrated();
});
useEffect(() => {
// If already hydrated, no need to subscribe
if (hydrated) return;
// Subscribe to hydration completion event
// onFinishHydration returns an unsubscribe function
const unsubscribe = useWorkflowStore.persist.onFinishHydration(() => {
setHydrated(true);
});
return unsubscribe;
}, [hydrated]);
return hydrated;
}
export default useHasHydrated;