Skip to content

Commit 31cd980

Browse files
committed
feat: ccs ls now shows numbered results with message previews
Rewrote ccs ls to query SQLite directly instead of delegating to cc-conversation-search list. Now shows: numbered results [1]-[N], project path, message count, last activity time, and first user message as preview. Writes to the same cache as search, so ccs go 1 works after both ccs ls and ccs search. Filters out command noise and plan boilerplate from previews.
1 parent 173bb07 commit 31cd980

File tree

1 file changed

+74
-1
lines changed

1 file changed

+74
-1
lines changed

bin/ccs

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,80 @@ case "$cmd" in
4545
;;
4646
ls|list)
4747
days="${1:-7}"
48-
cc-conversation-search list --days "$days"
48+
DB="${HOME}/.conversation-search/index.db"
49+
if [ ! -f "$DB" ]; then
50+
echo "No search index found. Run: ccs ix"
51+
exit 1
52+
fi
53+
python3 -c "
54+
import sqlite3, os, sys
55+
from datetime import datetime, timedelta
56+
57+
days = int(sys.argv[1])
58+
db = os.path.expanduser('~/.conversation-search/index.db')
59+
home = os.path.expanduser('~')
60+
conn = sqlite3.connect(db)
61+
c = conn.cursor()
62+
63+
cutoff = (datetime.now() - timedelta(days=days)).isoformat()
64+
65+
# Get sessions with stats
66+
c.execute('''
67+
SELECT session_id, project_path,
68+
COUNT(*) as msg_count,
69+
MAX(timestamp) as last_ts
70+
FROM messages
71+
WHERE is_tool_noise = 0 AND timestamp > ?
72+
GROUP BY session_id
73+
ORDER BY last_ts DESC
74+
''', (cutoff,))
75+
sessions = c.fetchall()
76+
77+
if not sessions:
78+
print(f'No sessions in the last {days} days.')
79+
conn.close()
80+
sys.exit(0)
81+
82+
# Cache for ccs go
83+
cache_path = os.path.expanduser('~/.ccs_last_results')
84+
with open(cache_path, 'w') as f:
85+
for sid, proj, _, _ in sessions:
86+
f.write(f'{sid}\t{proj or \"\"}\n')
87+
88+
# Get first user message for each session as preview
89+
previews = {}
90+
for sid, _, _, _ in sessions:
91+
c.execute('''
92+
SELECT substr(full_content, 1, 80)
93+
FROM messages
94+
WHERE session_id = ? AND message_type = 'user'
95+
AND is_tool_noise = 0 AND is_meta_conversation = 0
96+
AND length(full_content) > 10
97+
AND full_content NOT LIKE '<command-%'
98+
AND full_content NOT LIKE 'Implement the following plan%'
99+
ORDER BY timestamp ASC LIMIT 1
100+
''', (sid,))
101+
row = c.fetchone()
102+
previews[sid] = row[0].replace('\n', ' ').strip() if row else ''
103+
104+
conn.close()
105+
106+
print(f'\n Sessions (last {days} days)\n')
107+
for i, (sid, proj, count, last_ts) in enumerate(sessions, 1):
108+
proj_short = (proj or '').replace(home, '~')
109+
ts = last_ts[:16].replace('T', ' ') if last_ts else ''
110+
preview = previews.get(sid, '')
111+
if len(preview) > 60:
112+
preview = preview[:57] + '...'
113+
114+
print(f'\033[1;33m[{i}]\033[0m {ts} \033[0;36m{proj_short}\033[0m ({count} msgs)')
115+
if preview:
116+
print(f' {preview}')
117+
print()
118+
119+
print(f'\033[0;32m{len(sessions)} sessions.\033[0m Resume with: ccs go 1')
120+
print()
121+
" "$days" 2>&1
49122
;;
50123
go|resume)
51124
if [ -z "${1:-}" ]; then

0 commit comments

Comments
 (0)