eagle-mem 1.5.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -80,57 +80,6 @@ Next steps: $next_steps"
80
80
  "
81
81
  fi
82
82
 
83
- # Pending tasks from TaskAware loop
84
- pending_tasks=$(eagle_get_pending_tasks "$project")
85
-
86
- if [ -n "$pending_tasks" ]; then
87
- context+="
88
- === EAGLE MEM — Tasks ===
89
- Pending tasks for '$project':
90
- "
91
- first_pending=""
92
- while IFS='|' read -r tid title instructions status _ordinal; do
93
- [ -z "$tid" ] && continue
94
- local_marker=""
95
- if [ "$status" = "active" ]; then
96
- local_marker=" [ACTIVE]"
97
- elif [ -z "$first_pending" ]; then
98
- local_marker=" [NEXT]"
99
- first_pending="$tid"
100
- fi
101
- context+=" $tid. $title$local_marker"
102
- [ -n "$instructions" ] && context+=" — $instructions"
103
- context+="
104
- "
105
- done <<< "$pending_tasks"
106
-
107
- # Load context snapshot for the active/next task
108
- active_task=$(eagle_get_active_task "$project")
109
-
110
- if [ -z "$active_task" ] && [ -n "$first_pending" ]; then
111
- # Auto-activate the next pending task (atomic to prevent races
112
- # when multiple sessions start simultaneously)
113
- eagle_db "UPDATE tasks SET status = 'active', started_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
114
- WHERE id = $first_pending
115
- AND status = 'pending'
116
- AND NOT EXISTS (SELECT 1 FROM tasks WHERE project = '$(eagle_sql_escape "$project")' AND status = 'active');"
117
- active_task=$(eagle_get_active_task "$project")
118
- fi
119
-
120
- if [ -n "$active_task" ]; then
121
- IFS='|' read -r atid atitle ainstructions asnapshot <<< "$active_task"
122
- context+="
123
- Current task (#$atid): $atitle
124
- "
125
- [ -n "$ainstructions" ] && context+="Instructions: $ainstructions
126
- "
127
- [ -n "$asnapshot" ] && context+="Context: $asnapshot
128
- "
129
- context+="When done, tell the user to run /compact so Eagle Mem can save progress and load the next task.
130
- "
131
- fi
132
- fi
133
-
134
83
  # ─── Mirrored Claude memories ──────────────────────────────
135
84
 
136
85
  memories=$(eagle_list_claude_memories "$project" 5)
@@ -161,21 +110,28 @@ Recent plans for '$project':
161
110
  done <<< "$plans"
162
111
  fi
163
112
 
164
- # ─── Mirrored Claude tasks (synced) ──────────────────────
113
+ # ─── Claude Code tasks ───────────────────────────────────
165
114
 
166
- synced_tasks=$(eagle_db "SELECT subject, status FROM claude_tasks
115
+ synced_tasks=$(eagle_db "SELECT subject, status, blocked_by FROM claude_tasks
167
116
  WHERE project = '$(eagle_sql_escape "$project")'
168
117
  AND status IN ('in_progress', 'pending')
169
118
  AND updated_at > datetime('now', '-7 days')
170
- ORDER BY updated_at DESC LIMIT 5;")
119
+ ORDER BY
120
+ CASE status WHEN 'in_progress' THEN 0 ELSE 1 END,
121
+ updated_at DESC
122
+ LIMIT 10;")
171
123
  if [ -n "$synced_tasks" ]; then
172
124
  context+="
173
- === EAGLE MEM — Synced Tasks ===
174
- In-progress/pending tasks for '$project':
125
+ === EAGLE MEM — Tasks ===
126
+ Tasks for '$project':
175
127
  "
176
- while IFS='|' read -r tsubject tstatus; do
128
+ while IFS='|' read -r tsubject tstatus tblocked; do
177
129
  [ -z "$tsubject" ] && continue
178
- context+=" - [$tstatus] $tsubject
130
+ local_marker=""
131
+ if [ "$tblocked" != "[]" ] && [ -n "$tblocked" ]; then
132
+ local_marker=" (blocked)"
133
+ fi
134
+ context+=" - [$tstatus] $tsubject$local_marker
179
135
  "
180
136
  done <<< "$synced_tasks"
181
137
  fi
package/hooks/stop.sh CHANGED
@@ -141,12 +141,4 @@ if [ -n "$request" ] || [ -n "$completed" ] || [ -n "$learned" ]; then
141
141
  eagle_log "INFO" "Stop: summary saved for session=$session_id"
142
142
  fi
143
143
 
144
- # Mark active task as done only when Claude explicitly provided a summary
145
- if [ -n "$summary_block" ] && [ -n "$completed" ]; then
146
- completed_task_id=$(eagle_complete_active_task "$project")
147
- if [ -n "$completed_task_id" ]; then
148
- eagle_log "INFO" "Stop: marked task #$completed_task_id as done"
149
- fi
150
- fi
151
-
152
144
  exit 0
package/lib/db.sh CHANGED
@@ -126,25 +126,6 @@ eagle_search_summaries() {
126
126
  LIMIT $limit;"
127
127
  }
128
128
 
129
- eagle_get_pending_tasks() {
130
- local project; project=$(eagle_sql_escape "$1")
131
-
132
- eagle_db "SELECT id, title, instructions, status, ordinal
133
- FROM tasks
134
- WHERE project = '$project' AND status IN ('pending', 'active')
135
- ORDER BY ordinal ASC, id ASC;"
136
- }
137
-
138
- eagle_get_next_task() {
139
- local project; project=$(eagle_sql_escape "$1")
140
-
141
- eagle_db "SELECT id, title, instructions, context_snapshot
142
- FROM tasks
143
- WHERE project = '$project' AND status = 'pending'
144
- ORDER BY ordinal ASC, id ASC
145
- LIMIT 1;"
146
- }
147
-
148
129
  eagle_observation_exists() {
149
130
  local session_id; session_id=$(eagle_sql_escape "$1")
150
131
  local tool_name; tool_name=$(eagle_sql_escape "$2")
@@ -174,31 +155,6 @@ eagle_get_overview() {
174
155
  eagle_db "SELECT content FROM overviews WHERE project = '$project';"
175
156
  }
176
157
 
177
- eagle_activate_task() {
178
- local task_id; task_id=$(eagle_sql_int "$1")
179
- eagle_db "UPDATE tasks SET status = 'active', started_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id = $task_id;"
180
- }
181
-
182
- eagle_complete_active_task() {
183
- local project; project=$(eagle_sql_escape "$1")
184
- local active_id
185
- active_id=$(eagle_db "SELECT id FROM tasks WHERE project = '$project' AND status = 'active' LIMIT 1;")
186
- if [ -n "$active_id" ]; then
187
- local safe_id; safe_id=$(eagle_sql_int "$active_id")
188
- eagle_db "UPDATE tasks SET status = 'done', completed_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id = $safe_id;"
189
- echo "$active_id"
190
- fi
191
- }
192
-
193
- eagle_get_active_task() {
194
- local project; project=$(eagle_sql_escape "$1")
195
- eagle_db "SELECT id, title, instructions, context_snapshot
196
- FROM tasks
197
- WHERE project = '$project' AND status = 'active'
198
- ORDER BY ordinal ASC, id ASC
199
- LIMIT 1;"
200
- }
201
-
202
158
  eagle_search_code_chunks() {
203
159
  local query; query=$(eagle_sql_escape "$1")
204
160
  local project; project=$(eagle_sql_escape "$2")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eagle-mem",
3
- "version": "1.5.1",
3
+ "version": "1.6.0",
4
4
  "description": "Lightweight persistent memory for Claude Code — SQLite + FTS5, no daemon, no bloat",
5
5
  "bin": {
6
6
  "eagle-mem": "bin/eagle-mem"
package/scripts/help.sh CHANGED
@@ -20,7 +20,7 @@ echo -e " eagle-mem ${CYAN}<command>${RESET}"
20
20
  echo ""
21
21
  echo -e " ${BOLD}Commands:${RESET}"
22
22
  echo -e " ${CYAN}search${RESET} Search past sessions, files, and observations"
23
- echo -e " ${CYAN}tasks${RESET} Manage tracked tasks (add, done, block, list)"
23
+ echo -e " ${CYAN}tasks${RESET} View mirrored Claude Code tasks"
24
24
  echo -e " ${CYAN}overview${RESET} View or set project overview"
25
25
  echo -e " ${CYAN}memories${RESET} Browse and search Claude Code memories, plans, and tasks"
26
26
  echo -e " ${CYAN}scan${RESET} Analyze a project and generate an overview"
@@ -35,8 +35,8 @@ echo ""
35
35
  echo -e " ${BOLD}Examples:${RESET}"
36
36
  echo -e " ${DIM}\$${RESET} eagle-mem search \"auth bug\" ${DIM}# Search memory${RESET}"
37
37
  echo -e " ${DIM}\$${RESET} eagle-mem search --timeline ${DIM}# Recent sessions${RESET}"
38
- echo -e " ${DIM}\$${RESET} eagle-mem tasks ${DIM}# List tasks${RESET}"
39
- echo -e " ${DIM}\$${RESET} eagle-mem tasks add \"Fix X\" ${DIM}# Add a task${RESET}"
38
+ echo -e " ${DIM}\$${RESET} eagle-mem tasks ${DIM}# View pending tasks${RESET}"
39
+ echo -e " ${DIM}\$${RESET} eagle-mem tasks search \"X\" ${DIM}# Search task history${RESET}"
40
40
  echo -e " ${DIM}\$${RESET} eagle-mem overview ${DIM}# View overview${RESET}"
41
41
  echo -e " ${DIM}\$${RESET} eagle-mem scan . ${DIM}# Scan current project${RESET}"
42
42
  echo -e " ${DIM}\$${RESET} eagle-mem index . ${DIM}# Index source files${RESET}"
@@ -53,11 +53,11 @@ echo -e " ${DOT} Injects relevant memory at session start"
53
53
  echo -e " ${DOT} Searches past sessions when you ask related questions"
54
54
  echo -e " ${DOT} Tracks file operations across sessions"
55
55
  echo -e " ${DOT} Mirrors Claude Code memories, plans, and tasks into FTS5-searchable storage"
56
- echo -e " ${DOT} Provides task management for complex multi-step work"
56
+ echo -e " ${DOT} Uses Claude Code's native task system (TaskCreate/TaskUpdate) for multi-step work"
57
57
  echo ""
58
58
  echo -e " ${BOLD}Skills${RESET} ${DIM}(available inside Claude Code):${RESET}"
59
59
  echo -e " ${CYAN}/eagle-mem-search${RESET} Search past sessions and observations"
60
- echo -e " ${CYAN}/eagle-mem-tasks${RESET} Break work into tracked subtasks"
60
+ echo -e " ${CYAN}/eagle-mem-tasks${RESET} Break work into Claude Code tasks with dependencies"
61
61
  echo -e " ${CYAN}/eagle-mem-overview${RESET} Generate a persistent project summary"
62
62
  echo -e " ${CYAN}/eagle-mem-index${RESET} Index source files for code search"
63
63
  echo -e " ${CYAN}/eagle-mem-scan${RESET} Scan and analyze a project"
package/scripts/search.sh CHANGED
@@ -249,7 +249,7 @@ search_stats() {
249
249
  sessions=$(eagle_db "SELECT COUNT(*) FROM sessions WHERE project = '$p';")
250
250
  summaries=$(eagle_db "SELECT COUNT(*) FROM summaries WHERE project = '$p';")
251
251
  observations=$(eagle_db "SELECT COUNT(*) FROM observations o JOIN sessions s ON s.id = o.session_id WHERE s.project = '$p';")
252
- tasks=$(eagle_db "SELECT COUNT(*) FROM tasks WHERE project = '$p';")
252
+ tasks=$(eagle_db "SELECT COUNT(*) FROM claude_tasks WHERE project = '$p';")
253
253
  local chunks
254
254
  chunks=$(eagle_db "SELECT COUNT(*) FROM code_chunks WHERE project = '$p';")
255
255
 
package/scripts/tasks.sh CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env bash
2
2
  # ═══════════════════════════════════════════════════════════
3
- # Eagle Mem — Tasks
4
- # CLI wrapper for task management (replaces raw SQL in skills)
3
+ # Eagle Mem — Tasks (read-only viewer of Claude Code tasks)
4
+ # Claude Code manages task state via TaskCreate/TaskUpdate;
5
+ # Eagle Mem mirrors it and displays it here.
5
6
  # ═══════════════════════════════════════════════════════════
6
7
  set -euo pipefail
7
8
 
@@ -22,28 +23,25 @@ shift 2>/dev/null || true
22
23
  project=""
23
24
  json_output=false
24
25
 
25
- # Extract global options from remaining args
26
- args=()
27
-
28
26
  show_help() {
29
- echo -e " ${BOLD}eagle-mem tasks${RESET} — Manage tracked tasks"
27
+ echo -e " ${BOLD}eagle-mem tasks${RESET} — View mirrored Claude Code tasks"
30
28
  echo ""
31
29
  echo -e " ${BOLD}Usage:${RESET}"
32
- echo -e " eagle-mem tasks ${DIM}# list pending tasks${RESET}"
33
- echo -e " eagle-mem tasks ${CYAN}list${RESET} ${DIM}# list all tasks${RESET}"
34
- echo -e " eagle-mem tasks ${CYAN}add${RESET} <title> [instructions] ${DIM}# add a task${RESET}"
35
- echo -e " eagle-mem tasks ${CYAN}done${RESET} <id> ${DIM}# mark task complete${RESET}"
36
- echo -e " eagle-mem tasks ${CYAN}block${RESET} <id> ${DIM}# mark task blocked${RESET}"
37
- echo -e " eagle-mem tasks ${CYAN}context${RESET} <id> <snapshot> ${DIM}# set task context${RESET}"
38
- echo -e " eagle-mem tasks ${CYAN}clear${RESET} ${DIM}# remove all done tasks${RESET}"
30
+ echo -e " eagle-mem tasks ${DIM}# list pending/in-progress tasks${RESET}"
31
+ echo -e " eagle-mem tasks ${CYAN}list${RESET} ${DIM}# list all tasks${RESET}"
32
+ echo -e " eagle-mem tasks ${CYAN}search${RESET} <query> ${DIM}# search tasks by keyword${RESET}"
39
33
  echo ""
40
34
  echo -e " ${BOLD}Options:${RESET}"
41
35
  echo -e " ${CYAN}-p, --project${RESET} <name> Project name (default: current dir)"
42
36
  echo -e " ${CYAN}-j, --json${RESET} Output as JSON"
43
37
  echo ""
38
+ echo -e " ${DIM}Tasks are managed by Claude Code (TaskCreate/TaskUpdate).${RESET}"
39
+ echo -e " ${DIM}Eagle Mem automatically mirrors them for cross-session recall.${RESET}"
40
+ echo ""
44
41
  exit 0
45
42
  }
46
43
 
44
+ args=()
47
45
  while [ $# -gt 0 ]; do
48
46
  case "$1" in
49
47
  --project|-p) project="$2"; shift 2 ;;
@@ -63,24 +61,28 @@ tasks_list() {
63
61
 
64
62
  local where_status=""
65
63
  case "$filter" in
66
- pending) where_status="AND status IN ('pending', 'active')" ;;
67
- done) where_status="AND status = 'done'" ;;
68
- all) where_status="" ;;
64
+ pending) where_status="AND status IN ('pending', 'in_progress')" ;;
65
+ completed) where_status="AND status = 'completed'" ;;
66
+ all) where_status="" ;;
69
67
  esac
70
68
 
71
69
  if [ "$json_output" = true ]; then
72
- eagle_db_json "SELECT id, title, instructions, status, ordinal, context_snapshot, completed_at, created_at
73
- FROM tasks
70
+ eagle_db_json "SELECT source_task_id, subject, description, status, blocks, blocked_by, updated_at
71
+ FROM claude_tasks
74
72
  WHERE project = '$project_sql' $where_status
75
- ORDER BY ordinal ASC, id ASC;"
73
+ ORDER BY updated_at DESC
74
+ LIMIT 20;"
76
75
  return
77
76
  fi
78
77
 
79
78
  local results
80
- results=$(eagle_db "SELECT id, title, status, ordinal, instructions
81
- FROM tasks
79
+ results=$(eagle_db "SELECT source_task_id, subject, status, blocked_by, description
80
+ FROM claude_tasks
82
81
  WHERE project = '$project_sql' $where_status
83
- ORDER BY ordinal ASC, id ASC;")
82
+ ORDER BY
83
+ CASE status WHEN 'in_progress' THEN 0 WHEN 'pending' THEN 1 ELSE 2 END,
84
+ updated_at DESC
85
+ LIMIT 20;")
84
86
 
85
87
  if [ -z "$results" ]; then
86
88
  eagle_dim "No tasks for project '$project'"
@@ -92,170 +94,74 @@ tasks_list() {
92
94
  echo -e " ${DIM}─────────────────────────────────────${RESET}"
93
95
  echo ""
94
96
 
95
- while IFS='|' read -r tid title status ordinal instructions; do
97
+ while IFS='|' read -r tid subject status blocked_by desc; do
96
98
  [ -z "$tid" ] && continue
97
99
  local icon marker
98
100
  case "$status" in
99
- active) icon="${CYAN}▶${RESET}"; marker=" ${CYAN}[ACTIVE]${RESET}" ;;
100
- pending) icon="${DIM}○${RESET}"; marker="" ;;
101
- done) icon="${GREEN}✓${RESET}"; marker=" ${DIM}[DONE]${RESET}" ;;
102
- blocked) icon="${RED}✗${RESET}"; marker=" ${RED}[BLOCKED]${RESET}" ;;
103
- *) icon="$DOT"; marker="" ;;
101
+ in_progress) icon="${CYAN}>${RESET}"; marker=" ${CYAN}[in_progress]${RESET}" ;;
102
+ pending) icon="${DIM}o${RESET}"; marker="" ;;
103
+ completed) icon="${GREEN}+${RESET}"; marker=" ${DIM}[completed]${RESET}" ;;
104
+ deleted) icon="${RED}x${RESET}"; marker=" ${RED}[deleted]${RESET}" ;;
105
+ *) icon="$DOT"; marker="" ;;
104
106
  esac
105
- echo -e " ${icon} ${BOLD}#$tid${RESET} $title$marker"
106
- [ -n "$instructions" ] && echo -e " ${DIM}$instructions${RESET}"
107
+ if [ "$blocked_by" != "[]" ] && [ -n "$blocked_by" ]; then
108
+ marker+=" ${DIM}(blocked)${RESET}"
109
+ fi
110
+ echo -e " ${icon} ${BOLD}$tid${RESET} $subject$marker"
111
+ [ -n "$desc" ] && echo -e " ${DIM}$(echo "$desc" | cut -c1-80)${RESET}"
107
112
  done <<< "$results"
108
113
  echo ""
109
114
  }
110
115
 
111
- # ─── Add task ─────────────────────────────────────────────
112
-
113
- tasks_add() {
114
- local title="${args[0]:-}"
115
- local instructions="${args[1]:-}"
116
-
117
- if [ -z "$title" ]; then
118
- eagle_err "Usage: eagle-mem tasks add <title> [instructions]"
119
- exit 1
120
- fi
121
-
122
- local title_sql; title_sql=$(eagle_sql_escape "$title")
123
- local instr_sql; instr_sql=$(eagle_sql_escape "$instructions")
124
-
125
- local max_ord
126
- max_ord=$(eagle_db "SELECT COALESCE(MAX(ordinal), 0) FROM tasks WHERE project = '$project_sql';")
127
- local next_ord=$((max_ord + 1))
128
-
129
- local new_id
130
- new_id=$(eagle_db "INSERT INTO tasks (project, title, instructions, ordinal)
131
- VALUES ('$project_sql', '$title_sql', '$instr_sql', $next_ord);
132
- SELECT last_insert_rowid();")
133
-
134
- if [ "$json_output" = true ]; then
135
- jq -nc --arg id "$new_id" --arg title "$title" --argjson ord "$next_ord" \
136
- '{id: ($id | tonumber), title: $title, ordinal: $ord}'
137
- return
138
- fi
139
-
140
- eagle_ok "Task #$new_id added: $title"
141
- }
142
-
143
- # ─── Done ─────────────────────────────────────────────────
144
-
145
- tasks_done() {
146
- local task_id="${args[0]:-}"
116
+ # ─── Search tasks ─────────────────────────────────────────
147
117
 
148
- if [ -z "$task_id" ]; then
149
- eagle_err "Usage: eagle-mem tasks done <id>"
118
+ tasks_search() {
119
+ local query="${args[0]:-}"
120
+ if [ -z "$query" ]; then
121
+ eagle_err "Usage: eagle-mem tasks search <query>"
150
122
  exit 1
151
123
  fi
152
124
 
153
- if ! [[ "$task_id" =~ ^[0-9]+$ ]]; then
154
- eagle_err "Task ID must be a number, got: $task_id"
155
- exit 1
156
- fi
157
-
158
- local changed
159
- changed=$(eagle_db "UPDATE tasks SET status = 'done', completed_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
160
- WHERE id = $task_id AND project = '$project_sql';
161
- SELECT changes();")
162
-
163
- if [ "${changed:-0}" -eq 0 ]; then
164
- eagle_err "Task #$task_id not found in project '$project'"
165
- exit 1
166
- fi
167
-
168
- local title
169
- title=$(eagle_db "SELECT title FROM tasks WHERE id = $task_id AND project = '$project_sql';")
170
-
171
125
  if [ "$json_output" = true ]; then
172
- jq -nc --arg id "$task_id" '{id: ($id | tonumber), status: "done"}'
126
+ local query_sql; query_sql=$(eagle_fts_sanitize "$query")
127
+ query_sql=$(eagle_sql_escape "$query_sql")
128
+ eagle_db_json "SELECT t.source_task_id, t.subject, t.status, t.description, t.updated_at
129
+ FROM claude_tasks t
130
+ JOIN claude_tasks_fts f ON f.rowid = t.id
131
+ WHERE claude_tasks_fts MATCH '$query_sql'
132
+ AND t.project = '$project_sql'
133
+ ORDER BY rank
134
+ LIMIT 10;"
173
135
  return
174
136
  fi
175
137
 
176
- eagle_ok "Task #$task_id done: $title"
177
- }
178
-
179
- # ─── Block ────────────────────────────────────────────────
180
-
181
- tasks_block() {
182
- local task_id="${args[0]:-}"
183
-
184
- if [ -z "$task_id" ]; then
185
- eagle_err "Usage: eagle-mem tasks block <id>"
186
- exit 1
187
- fi
188
-
189
- if ! [[ "$task_id" =~ ^[0-9]+$ ]]; then
190
- eagle_err "Task ID must be a number, got: $task_id"
191
- exit 1
192
- fi
193
-
194
- local changed
195
- changed=$(eagle_db "UPDATE tasks SET status = 'blocked' WHERE id = $task_id AND project = '$project_sql';
196
- SELECT changes();")
197
-
198
- if [ "${changed:-0}" -eq 0 ]; then
199
- eagle_err "Task #$task_id not found in project '$project'"
200
- exit 1
201
- fi
202
-
203
- if [ "$json_output" = true ]; then
204
- jq -nc --arg id "$task_id" '{id: ($id | tonumber), status: "blocked"}'
205
- return
206
- fi
207
-
208
- eagle_ok "Task #$task_id blocked"
209
- }
210
-
211
- # ─── Context snapshot ─────────────────────────────────────
212
-
213
- tasks_context() {
214
- local task_id="${args[0]:-}"
215
- local snapshot="${args[1]:-}"
216
-
217
- if [ -z "$task_id" ] || [ -z "$snapshot" ]; then
218
- eagle_err "Usage: eagle-mem tasks context <id> <snapshot>"
219
- exit 1
220
- fi
221
-
222
- if ! [[ "$task_id" =~ ^[0-9]+$ ]]; then
223
- eagle_err "Task ID must be a number, got: $task_id"
224
- exit 1
225
- fi
226
-
227
- local snap_sql; snap_sql=$(eagle_sql_escape "$snapshot")
228
- local changed
229
- changed=$(eagle_db "UPDATE tasks SET context_snapshot = '$snap_sql' WHERE id = $task_id AND project = '$project_sql';
230
- SELECT changes();")
231
-
232
- if [ "${changed:-0}" -eq 0 ]; then
233
- eagle_err "Task #$task_id not found in project '$project'"
234
- exit 1
235
- fi
138
+ local results
139
+ local query_sql; query_sql=$(eagle_fts_sanitize "$query")
140
+ query_sql=$(eagle_sql_escape "$query_sql")
141
+ results=$(eagle_db "SELECT t.source_task_id, t.subject, t.status, t.description
142
+ FROM claude_tasks t
143
+ JOIN claude_tasks_fts f ON f.rowid = t.id
144
+ WHERE claude_tasks_fts MATCH '$query_sql'
145
+ AND t.project = '$project_sql'
146
+ ORDER BY rank
147
+ LIMIT 10;")
236
148
 
237
- if [ "$json_output" = true ]; then
238
- jq -nc --arg id "$task_id" '{id: ($id | tonumber), context_snapshot: true}'
149
+ if [ -z "$results" ]; then
150
+ eagle_dim "No tasks matching '$query'"
239
151
  return
240
152
  fi
241
153
 
242
- eagle_ok "Context saved for task #$task_id"
243
- }
244
-
245
- # ─── Clear done tasks ────────────────────────────────────
246
-
247
- tasks_clear() {
248
- local count
249
- count=$(eagle_db "SELECT COUNT(*) FROM tasks WHERE project = '$project_sql' AND status = 'done';")
250
-
251
- eagle_db "DELETE FROM tasks WHERE project = '$project_sql' AND status = 'done';"
252
-
253
- if [ "$json_output" = true ]; then
254
- jq -nc --argjson cleared "${count:-0}" '{cleared: $cleared}'
255
- return
256
- fi
154
+ echo ""
155
+ echo -e " ${BOLD}Task search:${RESET} $query"
156
+ echo -e " ${DIM}─────────────────────────────────────${RESET}"
157
+ echo ""
257
158
 
258
- eagle_ok "Cleared ${count:-0} completed tasks"
159
+ while IFS='|' read -r tid subject status desc; do
160
+ [ -z "$tid" ] && continue
161
+ echo -e " ${BOLD}$tid${RESET} [$status] $subject"
162
+ [ -n "$desc" ] && echo -e " ${DIM}$(echo "$desc" | cut -c1-80)${RESET}"
163
+ done <<< "$results"
164
+ echo ""
259
165
  }
260
166
 
261
167
  # ─── Dispatch ─────────────────────────────────────────────
@@ -263,12 +169,9 @@ tasks_clear() {
263
169
  case "$action" in
264
170
  list) tasks_list "all" ;;
265
171
  pending) tasks_list "pending" ;;
266
- add) tasks_add ;;
267
- done) tasks_done ;;
268
- block) tasks_block ;;
269
- context) tasks_context ;;
270
- clear) tasks_clear ;;
271
- --help|-h) show_help ;;
172
+ completed) tasks_list "completed" ;;
173
+ search) tasks_search ;;
174
+ --help|-h) show_help ;;
272
175
  *)
273
176
  eagle_err "Unknown action: $action"
274
177
  eagle_dim " Run 'eagle-mem tasks --help' for options"
@@ -1,100 +1,92 @@
1
1
  ---
2
2
  name: eagle-mem-tasks
3
3
  description: >
4
- TaskAware Compact Loop — break complex work into database-tracked subtasks with compaction
5
- between each. Use when: 'eagle tasks', 'break this into tasks', 'create task plan',
6
- 'task loop', 'compact loop', 'eagle mem tasks'. Uses the eagle-mem CLI — never run raw sqlite3 queries.
4
+ TaskAware Compact Loop — break complex work into Claude Code tasks with dependencies,
5
+ compact between each. Use when: 'eagle tasks', 'break this into tasks', 'create task plan',
6
+ 'task loop', 'compact loop', 'eagle mem tasks'. Uses Claude Code's native TaskCreate/TaskUpdate.
7
7
  ---
8
8
 
9
9
  # Eagle Mem — TaskAware Compact Loop
10
10
 
11
- Break complex work into subtasks stored in Eagle Mem's database. Execute one task at a time, compact between each, and let Eagle Mem re-inject context for the next task.
11
+ Break complex work into subtasks using Claude Code's native task system. Execute one task at a time, compact between each, and let Eagle Mem re-inject task state for the next task.
12
12
 
13
13
  ## How it works
14
14
 
15
15
  1. **Plan**: Break the user's request into ordered subtasks
16
- 2. **Store**: Add each subtask via the CLI
17
- 3. **Execute**: Work on the current task (marked `[ACTIVE]`)
18
- 4. **Compact**: When done, tell the user to run `/compact`
19
- 5. **Resume**: After compact, SessionStart re-injects memory + loads the next task
20
- 6. **Repeat**: Until all tasks are done
16
+ 2. **Create**: Add each subtask via `TaskCreate` with dependencies via `addBlockedBy`
17
+ 3. **Execute**: Work on the current task (mark `in_progress` with `TaskUpdate`)
18
+ 4. **Complete**: Mark done with `TaskUpdate(completed)`, emit `<eagle-summary>`
19
+ 5. **Compact**: Tell the user to run `/compact`
20
+ 6. **Resume**: After compact, SessionStart re-injects memory + loads task state from Eagle Mem's mirror
21
+ 7. **Repeat**: Until all tasks are done
21
22
 
22
- ## Commands
23
+ ## Creating tasks
23
24
 
24
- ### List tasks
25
+ Use Claude Code's `TaskCreate` tool. Each task gets `pending` status automatically.
25
26
 
26
- ```bash
27
- eagle-mem tasks
28
- eagle-mem tasks list
29
- ```
30
-
31
- ### Add tasks
32
-
33
- When the user invokes `/eagle-mem-tasks` or asks to break work into tasks:
34
-
35
- 1. Analyze the request and break it into 3-8 focused subtasks
36
- 2. Each task should be completable in one context window
37
- 3. Add tasks using the CLI:
27
+ For tasks that depend on earlier work, use `addBlockedBy` in `TaskUpdate`:
38
28
 
39
- ```bash
40
- eagle-mem tasks add "Set up project structure" "Install deps, create folders, init config"
41
- eagle-mem tasks add "Implement auth middleware" "JWT validation, role checks, error responses"
42
- eagle-mem tasks add "Build CRUD endpoints" "Users and posts REST API with validation"
43
29
  ```
30
+ TaskCreate({ subject: "Set up project structure", description: "Install deps, create folders, init config" })
31
+ TaskCreate({ subject: "Implement auth middleware", description: "JWT validation, role checks, error responses" })
32
+ TaskCreate({ subject: "Build CRUD endpoints", description: "Users and posts REST API with validation" })
44
33
 
45
- 4. Show the task plan to the user for confirmation
46
- 5. After confirmation, start working on task #1
47
-
48
- ### Complete a task
49
-
50
- ```bash
51
- eagle-mem tasks done <id>
34
+ // Then set dependencies:
35
+ TaskUpdate({ taskId: "3", addBlockedBy: ["1", "2"] })
52
36
  ```
53
37
 
54
- After marking done:
55
- 1. Emit your `<eagle-summary>` block
56
- 2. Tell the user: **"Task #N complete. Run `/compact` to save progress and load the next task."**
38
+ ## Working on a task
57
39
 
58
- ### Block a task
40
+ 1. Call `TaskUpdate({ taskId: "N", status: "in_progress" })` before starting work
41
+ 2. Do the work
42
+ 3. Call `TaskUpdate({ taskId: "N", status: "completed" })` when done
43
+ 4. Emit your `<eagle-summary>` block
44
+ 5. Tell the user: **"Task complete. Run `/compact` to save progress and load the next task."**
59
45
 
60
- ```bash
61
- eagle-mem tasks block <id>
62
- ```
63
-
64
- ### Set context snapshot
46
+ ## Viewing tasks
65
47
 
66
- For tasks that depend on decisions from earlier tasks:
48
+ Use `TaskList` to see all tasks, or the CLI for cross-session history:
67
49
 
68
50
  ```bash
69
- eagle-mem tasks context <id> "Using JWT with RS256, sessions stored in Redis"
51
+ eagle-mem tasks # pending/in-progress (from mirror)
52
+ eagle-mem tasks list # all tasks
53
+ eagle-mem tasks search <q> # FTS5 search across task history
70
54
  ```
71
55
 
72
- ### Clear completed tasks
56
+ ## Cross-session context
73
57
 
74
- ```bash
75
- eagle-mem tasks clear
76
- ```
58
+ When a task depends on decisions made in earlier tasks, put that context in the task's `description` field — it persists across compactions via Eagle Mem's mirror.
77
59
 
78
- ## Options
60
+ For example, if task 1 decides to use JWT with RS256:
79
61
 
80
- | Flag | Description |
81
- |------|-------------|
82
- | `-p, --project <name>` | Target a specific project (default: current directory) |
83
- | `-j, --json` | Output as JSON |
62
+ ```
63
+ TaskUpdate({ taskId: "2", description: "Implement auth middleware. Decision from task 1: using JWT with RS256, sessions stored in Redis." })
64
+ ```
84
65
 
85
66
  ## Task design guidelines
86
67
 
87
- - Each task should be **self-contained** — completable without mid-execution context from a previous task
88
- - Include instructions with enough detail that a fresh context window can pick it up
89
- - Use context snapshots for tasks that depend on decisions from earlier tasks
90
- - Order tasks so that foundational work comes first (schema before API, API before UI)
68
+ - Each task should be **self-contained** — completable in one context window
69
+ - Include enough detail in `description` that a fresh context window can pick it up
70
+ - Use `addBlockedBy` for tasks that depend on earlier tasks
71
+ - Order tasks so foundational work comes first (schema before API, API before UI)
72
+ - Keep tasks focused: 3-8 tasks per plan
91
73
 
92
74
  ## The compact cycle
93
75
 
94
76
  ```
95
- User request Plan tasks Execute task 1 /compact
96
- Eagle Mem saves summary Context cleared → Memory re-injected
97
- Task 2 loaded as [ACTIVE] Execute task 2 /compact
98
- ... repeat until all tasks done ...
99
- Final summary: "All N tasks complete."
77
+ User request -> Plan tasks (TaskCreate) -> Execute task 1 (TaskUpdate: in_progress)
78
+ -> Complete task 1 (TaskUpdate: completed) -> /compact
79
+ -> Eagle Mem saves summary -> Context cleared -> Task state re-injected
80
+ -> Execute task 2 -> /compact
81
+ -> ... repeat until all tasks done ...
82
+ -> Final summary: "All N tasks complete."
100
83
  ```
84
+
85
+ ## Status reference
86
+
87
+ | Status | Meaning |
88
+ |---|---|
89
+ | `pending` | Not started yet |
90
+ | `in_progress` | Currently being worked on |
91
+ | `completed` | Done |
92
+ | `deleted` | Removed |