---
phase: 05-search
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - src/lib/components/SearchBar.svelte
  - src/lib/components/FilterBar.svelte
  - src/lib/types/search.ts
autonomous: true

must_haves:
  truths:
    - "Search input is visible at top of page"
    - "Filter controls (type, tags, date) are visible alongside search"
    - "User can type in search input"
    - "User can interact with filter controls"
  artifacts:
    - path: "src/lib/components/SearchBar.svelte"
      provides: "Text search input with debounced value binding"
      min_lines: 40
    - path: "src/lib/components/FilterBar.svelte"
      provides: "Filter controls for type, tags, and date range"
      min_lines: 60
    - path: "src/lib/types/search.ts"
      provides: "SearchFilters interface and default values"
      exports: ["SearchFilters", "defaultFilters", "hasActiveFilters"]
  key_links:
    - from: "src/lib/components/SearchBar.svelte"
      to: "parent component"
      via: "$bindable value prop"
      pattern: "value = \\$bindable"
    - from: "src/lib/components/FilterBar.svelte"
      to: "parent component"
      via: "onchange callback prop"
      pattern: "onchange.*SearchFilters"
---

<objective>
Create the search and filter UI components with type definitions.

Purpose: Establish the visual search/filter interface that users interact with. These components emit filter state changes but do not perform filtering themselves.
Output: SearchBar.svelte, FilterBar.svelte, and search.ts type definitions ready for integration.
</objective>

<execution_context>
@/home/tho/.claude/get-shit-done/workflows/execute-plan.md
@/home/tho/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/05-search/05-CONTEXT.md
@.planning/phases/05-search/05-RESEARCH.md
@src/lib/components/EntryList.svelte
@src/lib/stores/preferences.svelte.ts
</context>

<tasks>

<task type="auto">
  <name>Task 1: Create search types and utility functions</name>
  <files>src/lib/types/search.ts</files>
  <action>
Create the SearchFilters interface and related utilities:

```typescript
export interface SearchFilters {
  query: string;
  tags: string[];
  type: 'task' | 'thought' | 'all';
  dateRange: {
    start: string | null;
    end: string | null;
  };
}

export const defaultFilters: SearchFilters = {
  query: '',
  tags: [],
  type: 'all',
  dateRange: { start: null, end: null }
};

export function hasActiveFilters(filters: SearchFilters): boolean {
  return (
    filters.query.length >= 2 ||
    filters.tags.length > 0 ||
    filters.type !== 'all' ||
    filters.dateRange.start !== null ||
    filters.dateRange.end !== null
  );
}

// Date preset helper for quick date range selection
export function getDatePreset(preset: 'today' | 'week' | 'month'): { start: string; end: string } {
  const now = new Date();
  const end = now.toISOString().split('T')[0];

  let start: Date;
  switch (preset) {
    case 'today':
      start = now;
      break;
    case 'week':
      start = new Date(now);
      start.setDate(start.getDate() - 7);
      break;
    case 'month':
      start = new Date(now);
      start.setMonth(start.getMonth() - 1);
      break;
  }

  return {
    start: start.toISOString().split('T')[0],
    end
  };
}
```
  </action>
  <verify>TypeScript compiles without errors: `npx tsc --noEmit`</verify>
  <done>SearchFilters interface exported and importable from other files</done>
</task>

<task type="auto">
  <name>Task 2: Create SearchBar component with debounced input</name>
  <files>src/lib/components/SearchBar.svelte</files>
  <action>
Create SearchBar.svelte with:
- Text input with placeholder 'Search entries... (press "/")'
- Debounced value binding (300ms delay, using $effect cleanup pattern)
- Only trigger search when query >= 2 characters OR when cleared to empty
- Bindable value prop for parent to receive debounced search term
- Styling: full width, px-4 py-2, border rounded-lg, focus ring

Props interface:
```typescript
interface Props {
  value: string;  // bindable - the debounced search query
}
```

Implementation notes:
- Use internal $state for inputValue (immediate user typing)
- Use $effect with setTimeout/clearTimeout for debounce
- Update the bound value only after debounce completes
- Match existing Tailwind styling patterns from other components
  </action>
  <verify>Component renders without errors when imported</verify>
  <done>SearchBar accepts text input and exposes debounced value via $bindable prop</done>
</task>

<task type="auto">
  <name>Task 3: Create FilterBar component with type, tag, and date controls</name>
  <files>src/lib/components/FilterBar.svelte</files>
  <action>
Create FilterBar.svelte with:

1. Type filter - three-state toggle (All / Tasks / Thoughts):
   - Use button group with active state highlighting
   - Default: 'all'

2. Tag filter - multi-select from available tags:
   - Re-use existing Svelecte pattern from TagInput.svelte
   - Multiple selection enabled
   - AND logic (handled by filtering logic in Plan 02)

3. Date range filter:
   - Quick preset buttons: Today, This week, This month
   - Custom range: two native date inputs (start/end)
   - Use getDatePreset helper from search.ts

4. Clear/Reset button:
   - Only visible when hasActiveFilters() returns true
   - Resets all filters to defaultFilters

Props interface:
```typescript
interface Props {
  filters: SearchFilters;
  availableTags: Tag[];
  onchange: (filters: SearchFilters) => void;
}
```

Layout:
- Horizontal flex wrap on desktop
- Stack vertically on mobile (use flex-wrap and gap)
- Each filter group visually separated

Styling notes:
- Match existing component patterns (border-gray-200, rounded-lg, focus:ring-2)
- Active type button: bg-blue-100 text-blue-700
- Inactive type button: bg-white text-gray-600 hover:bg-gray-50
  </action>
  <verify>Component renders with all filter controls visible and interactive</verify>
  <done>FilterBar displays type toggle, tag selector, date range controls, and clear button (when filters active)</done>
</task>

</tasks>

<verification>
- `npm run check` passes (Svelte and TypeScript)
- SearchBar and FilterBar import without errors
- Type definitions are correct and exported
</verification>

<success_criteria>
- SearchBar.svelte renders with debounced text input
- FilterBar.svelte renders with all filter controls (type, tags, date range)
- Clear button appears only when filters are active
- All components follow existing project patterns
</success_criteria>

<output>
After completion, create `.planning/phases/05-search/05-01-SUMMARY.md`
</output>
