Skip to content

Commit a2552c6

Browse files
lzwjavaclaude
andcommitted
feat: improve /search and /export commands
- /search without query now uses previous user message - /export now copies markdown format to clipboard instead of JSON file - Add /export to tab completion - Readable format with sections separated by lines Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent c8e5260 commit a2552c6

3 files changed

Lines changed: 61 additions & 13 deletions

File tree

iclaw/commands/export.py

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import json
1+
import pyperclip
22
from datetime import datetime
33

44

@@ -7,18 +7,51 @@ def handle_export_command(messages, tool_logs):
77
print("No conversation history to export.")
88
return
99

10-
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
11-
filename = f"iclaw_session_{timestamp}.json"
10+
lines = [
11+
"# Conversation Export",
12+
f"Exported at: {datetime.now().isoformat()}",
13+
"",
14+
"=" * 80,
15+
"",
16+
]
1217

13-
export_data = {
14-
"exported_at": datetime.now().isoformat(),
15-
"messages": messages,
16-
"tool_logs": tool_logs,
17-
}
18+
for i, msg in enumerate(messages):
19+
role = msg.get("role", "unknown").upper()
20+
content = msg.get("content", "")
1821

19-
with open(filename, "w") as f:
20-
json.dump(export_data, f, indent=2)
22+
lines.append(f"## {role} (Message {i + 1})")
23+
lines.append("")
2124

25+
if content:
26+
lines.append(content)
27+
28+
if msg.get("tool_calls"):
29+
lines.append("")
30+
lines.append("**Tool Calls:**")
31+
for tc in msg["tool_calls"]:
32+
lines.append(
33+
f"- {tc['function']['name']}: {tc['function']['arguments']}"
34+
)
35+
36+
lines.append("")
37+
lines.append("-" * 80)
38+
lines.append("")
39+
40+
if tool_logs:
41+
lines.append("")
42+
lines.append("# Tool Execution Logs")
43+
lines.append("")
44+
for log in tool_logs:
45+
ts = datetime.fromtimestamp(log["timestamp"]).strftime("%H:%M:%S")
46+
lines.append(f"**[{ts}] {log['function']}**")
47+
lines.append(f"Args: {log['args']}")
48+
lines.append(f"Result: {log['result']}")
49+
lines.append("")
50+
lines.append("-" * 80)
51+
lines.append("")
52+
53+
output = "\n".join(lines)
54+
pyperclip.copy(output)
2255
print(
23-
f"Exported {len(messages)} messages and {len(tool_logs)} tool logs to {filename}"
56+
f"Exported {len(messages)} messages and {len(tool_logs)} tool logs to clipboard"
2457
)

iclaw/completer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"/help",
1717
"/clear",
1818
"/compact",
19+
"/export",
1920
".exit",
2021
]
2122

iclaw/main.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,22 @@ def main():
132132
log_level=log_level,
133133
)
134134
continue
135-
if user_input.startswith("/search "):
136-
query = user_input.split(maxsplit=1)[1]
135+
if user_input.startswith("/search") or user_input == "/search":
136+
if user_input.startswith("/search "):
137+
query = user_input.split(maxsplit=1)[1]
138+
else:
139+
# Use last user message as query
140+
last_user_msg = next(
141+
(m["content"] for m in reversed(messages) if m["role"] == "user"),
142+
None,
143+
)
144+
if not last_user_msg:
145+
print(
146+
"No previous message to search. Usage: /search <query>",
147+
file=sys.stderr,
148+
)
149+
continue
150+
query = last_user_msg
137151
search_context = web_search(query, num_results=5, provider=search_provider)
138152
if not copilot_token:
139153
log.log_info(f"\n{search_context}\n")

0 commit comments

Comments
 (0)