openclacky 0.6.3 → 0.6.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3a21b23940f55985b4d58e1ff4cc1f3f6b71a14a8035ae88cc9d5721248e91e9
4
- data.tar.gz: 42e4c3b910bdeb242ea9dd5e5d690b49612fadc1d59b3921facca593b7fa6bc0
3
+ metadata.gz: dcf90e79799d6f487ba77c084b9b3b72fc7c5252e2ffc7a3e56a0973bb9df977
4
+ data.tar.gz: 52a2e19427036920d29ee27c5021f731cfc924fc9c6800e22040a017f74c7fc7
5
5
  SHA512:
6
- metadata.gz: 823af49c74737e48affb60d4292787042470edf76b9566debd419177974379e18afa8611a1d00fdd3082a2d7863c8b6bc56f43ce887a7493d86600b9f8a6270d
7
- data.tar.gz: 44cbdfac975198bd766987e452415fd5b6758001501816f13c5bbb46a2206c34f52c61d1781a0ad8a40813c23add2291d2bc2e4a330733a76385b27452033fe6
6
+ metadata.gz: 90180817198ad434c4920c855e92215fafe0495f11b93cdf156e1a1a13239219bf3d68f061900265165cf897d601f6913a8815e5c22e60d341cdb3ea6b661bde
7
+ data.tar.gz: e09ba63257284794970bd5929d1e310465120e98fe5330be371cd5a00935976f1e537843b7d05e7532400f757564a8be860b3621125f665fecb30eb81ff76199
data/CHANGELOG.md CHANGED
@@ -7,6 +7,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.6.3] - 2026-02-01
11
+
12
+ ### Added
13
+ - Complete skill system with loader and core functionality
14
+ - Default skill support with auto-loading mechanism
15
+ - Skills CLI command for skill management (`clacky skills list/show/create`)
16
+ - Command suggestions UI component for better user guidance
17
+ - Skip safety check option for safe_shell tool
18
+ - UI2 component comprehensive test suite
19
+ - Token output control for file_reader and shell tools
20
+ - Grep max files limit configuration
21
+ - File_reader tool index support
22
+ - Web fetch content length limiting
23
+
24
+ ### Improved
25
+ - File_reader line range handling logic
26
+ - Message compression strategy (100 message compress)
27
+ - Inline input wrap line handling
28
+ - Cursor position calculation for multi-line inline input
29
+ - Theme adjustments for better visual experience
30
+ - Skill system integration with agent
31
+ - Gem-release skill metadata standardization
32
+ - Skill documentation with user experience summaries
33
+
34
+ ### Fixed
35
+ - Skill commands now properly pass through to agent
36
+ - Session restore data loading with -a or -c flags
37
+ - Inline input cursor positioning for wrapped lines
38
+ - Multi-line inline input cursor calculation
39
+
10
40
  ## [0.6.2] - 2026-01-30
11
41
 
12
42
  ### Added
@@ -0,0 +1,267 @@
1
+ # Why OpenClacky?
2
+
3
+ ## The Vision: AI-Powered Development for Everyone
4
+
5
+ **Clacky** is an open-source, CLI-first AI development assistant designed to make software creation accessible to non-technical users while remaining powerful enough for professional developers.
6
+
7
+ Our ultimate vision: **OpenClacky = Lovable + Supabase** — an open-source alternative that combines the ease-of-use of no-code platforms with the flexibility of a modern Rails application.
8
+
9
+ ---
10
+
11
+ ## The Problem
12
+
13
+ Building software today is still too hard for most people:
14
+
15
+ | Challenge | Current Solutions |
16
+ |-----------|-------------------|
17
+ | **Too technical** | Requires learning programming, DevOps, deployment |
18
+ | **Too expensive** | Enterprise tools cost $100+/month |
19
+ | **Too locked-in** | Vendor lock-in with proprietary platforms |
20
+ | **Too complex** | Modern tech stacks have steep learning curves |
21
+
22
+ Non-technical founders, designers, and product managers often have great ideas but can't build them. Existing AI tools either:
23
+ - **Are too technical** (Claude Code, GitHub Copilot)
24
+ - **Are too expensive** (Lovable $25+/month)
25
+ - **Lock you into proprietary platforms** (v0, Lovable)
26
+
27
+ ---
28
+
29
+ ## The Solution: Clacky
30
+
31
+ Clacky bridges the gap between no-code simplicity and developer-grade power.
32
+
33
+ ### Our Two-Part Strategy
34
+
35
+ #### Part 1: CLI for Everyone (Current Focus)
36
+
37
+ A command-line AI assistant that's approachable for non-technical users but powerful enough to rival Claude Code.
38
+
39
+ **Key Differentiators:**
40
+
41
+ ```
42
+ ┌─────────────────────────────────────────────────────────────┐
43
+ │ Clacky CLI Features │
44
+ ├─────────────────────────────────────────────────────────────┤
45
+ │ ✅ confirm_safes mode │ More automation than Claude │
46
+ │ ✅ Real-time cost monitor │ See token usage in real-time │
47
+ │ ✅ Session persistence │ Pause & resume your work │
48
+ │ ✅ SafeShell protection │ Commands made safe automatically│
49
+ │ ✅ Multi-API support │ DeepSeek, OpenRouter, OpenAI │
50
+ │ ✅ Skills system │ Extensible command shortcuts │
51
+ │ ✅ Open source │ MIT License - no vendor lock-in │
52
+ │ ✅ $0 monthly cost │ Pay only for API usage │
53
+ └─────────────────────────────────────────────────────────────┘
54
+ ```
55
+
56
+ **Why Non-Technical Users Love Clacky:**
57
+
58
+ 1. **Natural Language Commands**
59
+ ```
60
+ clacky agent "Create a REST API for user management"
61
+ clacky agent "Add authentication to my Rails app"
62
+ ```
63
+
64
+ 2. **Safe by Default**
65
+ - Dangerous commands (`rm`, `curl | sh`) are automatically made safe
66
+ - Files moved to trash instead of deleted
67
+ - Project boundaries enforced
68
+
69
+ 3. **Transparent Costs**
70
+ ```
71
+ 💰 Cost: $0.0042 (Claude 3.5 Sonnet)
72
+ 📊 Tokens: 1,250 in / 850 out
73
+ 🗜️ Compression saved: 60%
74
+ ```
75
+
76
+ 4. **Permission Modes for Every Situation**
77
+
78
+ | Mode | Behavior | Best For |
79
+ |------|----------|----------|
80
+ | `auto_approve` | Execute all tools automatically | Batch operations |
81
+ | `confirm_safes` | Auto-approve safe operations | Daily development |
82
+ | `confirm_edits` | Confirm file modifications | Careful work |
83
+ | `plan_only` | Generate plans only | Code review |
84
+
85
+ 5. **Session Recovery**
86
+ ```bash
87
+ clacky agent -c # Continue last session
88
+ clacky agent -l # List recent sessions
89
+ clacky agent -a 2 # Attach to specific session
90
+ ```
91
+
92
+ #### Part 2: AI-Ready Rails Template (Coming Soon)
93
+
94
+ ```
95
+ clacky new my_project
96
+ ```
97
+
98
+ A production-ready Rails application scaffold designed specifically for AI-powered development, including:
99
+
100
+ | Feature | Description |
101
+ |---------|-------------|
102
+ | 🔐 **Authentication** | Built-in login/registration with Devise |
103
+ | 🤖 **LLM Integration** | Pre-configured for Claude, OpenAI, DeepSeek |
104
+ | ⚡ **Async Jobs** | Sidekiq for background processing |
105
+ | 🔄 **WebSockets** | Action Cable for real-time features |
106
+ | 🎨 **Beautiful UI** | Tailwind CSS + Hotwire components |
107
+ | 📊 **Admin Dashboard** | ActiveAdmin or Avo integration |
108
+ | 🚀 **One-Click Deploy** | Docker + Kamal/Cloud66 ready |
109
+
110
+ **Why Rails?**
111
+
112
+ - Mature, stable, and well-documented
113
+ - Great for AI apps (LLM calls, async processing, web interface)
114
+ - Strong conventions reduce decision fatigue
115
+ - ActiveJob, Action Cable, Hotwire built-in
116
+
117
+ ---
118
+
119
+ ## Clacky vs. The Competition
120
+
121
+ | Feature | **Clacky** | Claude Code | Lovable | Cursor |
122
+ |---------|------------|-------------|---------|--------|
123
+ | **Target Users** | Non-technical + Devs | Developers only | Non-technical | Developers |
124
+ | **Interface** | CLI | CLI + IDE + Web | Web only | IDE |
125
+ | **Open Source** | ✅ MIT | ❌ Closed | ❌ Closed | ❌ Closed |
126
+ | **Monthly Cost** | $0 (API only) | $17-200 | $25-99+ | $20+ |
127
+ | **Self-Hosted** | ✅ Yes | ❌ No | ❌ No | ❌ No |
128
+ | **Multi-API** | ✅ DeepSeek, OpenRouter | ❌ Anthropic only | ❌ Limited | ❌ OpenAI only |
129
+ | **SafeShell** | ✅ Auto-protection | ⚠️ Manual | N/A | ⚠️ Manual |
130
+ | **Sessions** | ✅ Persistent | ⚠️ Limited | ⚠️ Limited | ⚠️ Limited |
131
+ | **Skills/Plugins** | ✅ Extensible | ❌ No | ❌ No | ⚠️ Limited |
132
+ | **Rails Template** | ✅ Coming soon | ❌ No | ⚠️ Limited | ❌ No |
133
+
134
+ ---
135
+
136
+ ## Why Now?
137
+
138
+ ### The AI Development Revolution
139
+
140
+ We're at a unique moment in software history:
141
+
142
+ 1. **AI models are now capable** of generating production-quality code
143
+ 2. **APIs are affordable** - DeepSeek is 95% cheaper than OpenAI
144
+ 3. **CLI is experiencing a renaissance** - Developers prefer terminal tools
145
+ 4. **Open source AI is viable** - No vendor lock-in
146
+
147
+ ### The Open Source Advantage
148
+
149
+ Unlike proprietary platforms, Clacky gives you:
150
+
151
+ - **Freedom**: Use any model, any API, any provider
152
+ - **Control**: Self-host everything, no data leaves your machine
153
+ - **Customization**: Modify the source code for your needs
154
+ - **Community**: Learn from others, contribute back
155
+ - **Longevity**: No risk of the platform shutting down
156
+
157
+ ---
158
+
159
+ ## Our Roadmap
160
+
161
+ ### Phase 1: CLI Excellence (Current)
162
+ - [x] Core agent with tool execution
163
+ - [x] confirm_safes mode (more automation)
164
+ - [x] Real-time cost monitoring
165
+ - [x] SafeShell protection
166
+ - [x] Session persistence
167
+ - [x] Skills system
168
+
169
+ ### Phase 2: Rails Template (Coming Soon)
170
+ - [ ] `clacky new` command
171
+ - [ ] Pre-configured authentication
172
+ - [ ] LLM integration ready
173
+ - [ ] Async job system
174
+ - [ ] WebSocket support
175
+ - [ ] Admin dashboard
176
+ - [ ] Docker + deployment configs
177
+
178
+ ### Phase 3: The Lovable Alternative
179
+ - [ ] Web-based project manager
180
+ - [ ] Visual component library
181
+ - [ ] Database schema designer
182
+ - [ ] One-click deployment
183
+
184
+ ---
185
+
186
+ ## Pricing Philosophy
187
+
188
+ We believe AI development tools should be accessible to everyone.
189
+
190
+ ```
191
+ ┌────────────────────────────────────────────────────────────┐
192
+ │ Clacky Pricing │
193
+ ├────────────────────────────────────────────────────────────┤
194
+ │ 📦 Clacky CLI │ $0/month (Open Source) │
195
+ │ • All features │ Pay only for API usage │
196
+ │ • No subscription │ Use DeepSeek, OpenRouter, etc. │
197
+ │ │ │
198
+ │ 🚀 Rails Template │ $0 (Open Source) │
199
+ │ • Full source code │ MIT License │
200
+ │ • Self-host │ No vendor lock-in │
201
+ │ │ │
202
+ │ 💎 Enterprise Support │ Contact us │
203
+ │ • Custom development│ Training & consulting │
204
+ └────────────────────────────────────────────────────────────┘
205
+ ```
206
+
207
+ ---
208
+
209
+ ## Get Started
210
+
211
+ ### Quick Install
212
+
213
+ ```bash
214
+ # One-line installation (macOS/Linux)
215
+ curl -sSL https://raw.githubusercontent.com/clacky-ai/open-clacky/main/scripts/install.sh | bash
216
+
217
+ # Or if you have Ruby 3.1+
218
+ gem install openclacky
219
+ ```
220
+
221
+ ### First Steps
222
+
223
+ ```bash
224
+ # Configure your API key
225
+ clacky config set
226
+
227
+ # Start the agent
228
+ clacky agent
229
+
230
+ # Or give it a task
231
+ clacky agent "Create a TODO list app"
232
+
233
+ # See all tools
234
+ clacky tools
235
+ ```
236
+
237
+ ---
238
+
239
+ ## Join Us
240
+
241
+ Clacky is an open-source project. We welcome contributions!
242
+
243
+ - **GitHub**: https://github.com/clacky-ai/open-clacky
244
+ - **Discord**: https://discord.gg/clacky
245
+ - **Twitter**: https://twitter.com/clacky_ai
246
+
247
+ ---
248
+
249
+ ## Summary
250
+
251
+ **Clacky** is for anyone who wants to build software but has been held back by technical complexity or expensive tools.
252
+
253
+ Whether you're a:
254
+ - 🎨 **Designer** who wants to prototype ideas
255
+ - 💼 **Product Manager** who wants to validate concepts
256
+ - 🚀 **Founder** who wants to build an MVP
257
+ - 👨‍💻 **Developer** who wants a more automated CLI
258
+
259
+ ...Clacky is here to help.
260
+
261
+ **The future of software development is accessible, open, and AI-powered.**
262
+
263
+ **Welcome to Clacky.**
264
+
265
+ ---
266
+
267
+ *Last updated: February 2025*
data/lib/clacky/agent.rb CHANGED
@@ -226,6 +226,17 @@ module Clacky
226
226
  # Check if done (no more tool calls needed)
227
227
  if response[:finish_reason] == "stop" || response[:tool_calls].nil? || response[:tool_calls].empty?
228
228
  @ui&.show_assistant_message(response[:content]) if response[:content] && !response[:content].empty?
229
+
230
+ # Debug: log why we're stopping
231
+ if @config.verbose && (response[:tool_calls].nil? || response[:tool_calls].empty?)
232
+ reason = response[:finish_reason] == "stop" ? "API returned finish_reason=stop" : "No tool calls in response"
233
+ @ui&.log("Stopping: #{reason}", level: :debug)
234
+ if response[:content] && response[:content].is_a?(String)
235
+ preview = response[:content].length > 200 ? response[:content][0...200] + "..." : response[:content]
236
+ @ui&.log("Response content: #{preview}", level: :debug)
237
+ end
238
+ end
239
+
229
240
  break
230
241
  end
231
242
 
@@ -526,7 +537,7 @@ module Clacky
526
537
  @ui&.show_progress
527
538
 
528
539
  # Compress messages if needed to reduce cost
529
- compress_messages_if_needed
540
+ compression_message = compress_messages_if_needed
530
541
 
531
542
  # Always send tools definitions to allow multi-step tool calling
532
543
  tools_to_send = @tool_registry.all_definitions
@@ -552,13 +563,16 @@ module Clacky
552
563
  retry
553
564
  else
554
565
  @ui&.show_error("Network failed after #{max_retries} retries: #{e.message}")
555
- raise Error, "Network connection failed after #{max_retries} retries: #{e.message}"
566
+ raise AgentError, "Network connection failed after #{max_retries} retries: #{e.message}"
556
567
  end
557
568
  end
558
569
 
559
570
  # Clear progress indicator (change to gray and show final time)
560
571
  @ui&.clear_progress
561
572
 
573
+ # Show compression message after clearing progress (so it doesn't get deleted)
574
+ @ui&.show_info(compression_message) if compression_message
575
+
562
576
  track_cost(response[:usage], raw_api_usage: response[:raw_api_usage])
563
577
 
564
578
  # Handle truncated responses (when max_tokens limit is reached)
@@ -613,7 +627,10 @@ module Clacky
613
627
  # Always include content field (some APIs require it even with tool_calls)
614
628
  # Use empty string instead of null for better compatibility
615
629
  msg[:content] = response[:content] || ""
616
- msg[:tool_calls] = format_tool_calls_for_api(response[:tool_calls]) if response[:tool_calls]
630
+ # Only add tool_calls if they actually exist (don't add empty arrays)
631
+ if response[:tool_calls]&.any?
632
+ msg[:tool_calls] = format_tool_calls_for_api(response[:tool_calls])
633
+ end
617
634
  @messages << msg
618
635
 
619
636
  response
@@ -655,7 +672,8 @@ module Clacky
655
672
  denied = true
656
673
  user_feedback = confirmation[:feedback]
657
674
  feedback = user_feedback if user_feedback
658
- results << build_denied_result(call, user_feedback)
675
+ system_injected = confirmation[:system_injected]
676
+ results << build_denied_result(call, user_feedback, system_injected)
659
677
 
660
678
  # Auto-deny all remaining tools
661
679
  remaining_calls = tool_calls[(index + 1)..-1] || []
@@ -663,7 +681,7 @@ module Clacky
663
681
  reason = user_feedback && !user_feedback.empty? ?
664
682
  user_feedback :
665
683
  "Auto-denied due to user rejection of previous tool"
666
- results << build_denied_result(remaining_call, reason)
684
+ results << build_denied_result(remaining_call, reason, system_injected)
667
685
  end
668
686
  break
669
687
  end
@@ -720,10 +738,11 @@ module Clacky
720
738
  error_message: e.message,
721
739
  backtrace: e.backtrace&.first(20) # Keep first 20 lines of backtrace
722
740
  }
723
-
741
+
724
742
  @hooks.trigger(:on_tool_error, call, e)
725
743
  @ui&.show_tool_error(e)
726
- results << build_error_result(call, e.message)
744
+ # Use build_denied_result with system_injected=true so LLM knows it can retry
745
+ results << build_denied_result(call, e.message, true)
727
746
  end
728
747
  end
729
748
 
@@ -736,35 +755,11 @@ module Clacky
736
755
 
737
756
  def observe(response, tool_results)
738
757
  # Add tool results as messages
739
- # Using OpenAI format which is compatible with most APIs through LiteLLM
740
-
741
- # CRITICAL: Tool results must be in the same order as tool_calls in the response
742
- # Claude/Bedrock API requires this strict ordering
758
+ # Use Client to format results based on API type (Anthropic vs OpenAI)
743
759
  return if tool_results.empty?
744
760
 
745
- # Create a map of tool_call_id -> result for quick lookup
746
- results_map = tool_results.each_with_object({}) do |result, hash|
747
- hash[result[:id]] = result
748
- end
749
-
750
- # Add results in the same order as the original tool_calls
751
- response[:tool_calls].each do |tool_call|
752
- result = results_map[tool_call[:id]]
753
- if result
754
- @messages << {
755
- role: "tool",
756
- tool_call_id: result[:id],
757
- content: result[:content]
758
- }
759
- else
760
- # This shouldn't happen, but add a fallback error result
761
- @messages << {
762
- role: "tool",
763
- tool_call_id: tool_call[:id],
764
- content: JSON.generate({ error: "Tool result missing" })
765
- }
766
- end
767
- end
761
+ formatted_messages = @client.format_tool_results(response, tool_results, model: @config.model)
762
+ formatted_messages.each { |msg| @messages << msg }
768
763
  end
769
764
 
770
765
  # Interrupt the agent's current run
@@ -1031,9 +1026,6 @@ module Clacky
1031
1026
 
1032
1027
  original_tokens = total_tokens
1033
1028
 
1034
- @ui&.show_info("Compressing history (~#{original_tokens} tokens -> ~#{TARGET_COMPRESSED_TOKENS} tokens)...")
1035
- @ui&.show_info("Compression level: #{@compression_level}")
1036
-
1037
1029
  # Find the system message (should be first)
1038
1030
  system_msg = @messages.find { |m| m[:role] == "system" }
1039
1031
 
@@ -1044,8 +1036,6 @@ module Clacky
1044
1036
  # Get messages to compress (everything except system and recent)
1045
1037
  messages_to_compress = @messages.reject { |m| m[:role] == "system" || recent_messages.include?(m) }
1046
1038
 
1047
- @ui&.show_info(" debug: total=#{@messages.size}, recent=#{recent_messages.size}, to_compress=#{messages_to_compress.size}")
1048
-
1049
1039
  return if messages_to_compress.empty?
1050
1040
 
1051
1041
  # Create hierarchical summary based on compression level
@@ -1065,7 +1055,8 @@ module Clacky
1065
1055
 
1066
1056
  final_tokens = total_message_tokens[:total]
1067
1057
 
1068
- @ui&.show_info("Compressed (~#{original_tokens} -> ~#{final_tokens} tokens, level #{@compression_level})")
1058
+ # Return compression message (to be shown after clearing progress)
1059
+ "History compressed (~#{original_tokens} -> ~#{final_tokens} tokens, level #{@compression_level})"
1069
1060
  end
1070
1061
 
1071
1062
  # Calculate how many recent messages to keep based on how much we need to compress
@@ -1446,9 +1437,8 @@ module Clacky
1446
1437
 
1447
1438
  # If preview detected an error, auto-deny and provide feedback
1448
1439
  if preview_error && preview_error[:error]
1449
- @ui&.show_warning("Tool call auto-denied due to preview error")
1450
1440
  feedback = build_preview_error_feedback(call[:name], preview_error)
1451
- return { approved: false, feedback: feedback }
1441
+ return { approved: false, feedback: feedback, system_injected: true }
1452
1442
  end
1453
1443
 
1454
1444
  # Request confirmation via UI
@@ -1479,7 +1469,7 @@ module Clacky
1479
1469
  private def build_preview_error_feedback(tool_name, error_info)
1480
1470
  case tool_name
1481
1471
  when "edit"
1482
- "The edit operation will fail because the old_string was not found in the file. " \
1472
+ "Tool edit denied: The edit operation will fail because the old_string was not found in the file. " \
1483
1473
  "Please use file_reader to read '#{error_info[:path]}' first, " \
1484
1474
  "find the correct string to replace, and try again with the exact string (including whitespace)."
1485
1475
  else
@@ -1607,9 +1597,7 @@ module Clacky
1607
1597
  file_size: file_content.length
1608
1598
  }
1609
1599
 
1610
- @ui&.show_file_error("String to replace not found in file")
1611
- @ui&.show_file_error("Looking for (first 100 chars):")
1612
- @ui&.show_file_error(old_string[0..100].inspect)
1600
+ @ui&.show_file_error("Edit file error")
1613
1601
  return {
1614
1602
  error: "String to replace not found in file",
1615
1603
  path: path,
@@ -1653,21 +1641,25 @@ module Clacky
1653
1641
  }
1654
1642
  end
1655
1643
 
1656
- def build_denied_result(call, user_feedback = nil)
1657
- message = if user_feedback && !user_feedback.empty?
1658
- "Tool use denied by user. User feedback: #{user_feedback}"
1659
- else
1660
- "Tool use denied by user"
1661
- end
1662
-
1663
- # For edit tool, remind AI to use the exact same old_string from the previous tool call
1664
- tool_content = {
1665
- error: message,
1666
- user_feedback: user_feedback
1667
- }
1644
+ def build_denied_result(call, user_feedback = nil, system_injected = false)
1645
+ if system_injected
1646
+ # System-generated feedback (e.g., from preview errors)
1647
+ tool_content = {
1648
+ error: "Tool #{call[:name]} denied: #{user_feedback}",
1649
+ system_injected: true
1650
+ }
1651
+ else
1652
+ # User manually denied or provided feedback
1653
+ message = if user_feedback && !user_feedback.empty?
1654
+ "Tool use denied by user. User feedback: #{user_feedback}"
1655
+ else
1656
+ "Tool use denied by user"
1657
+ end
1668
1658
 
1669
- if call[:name] == "edit"
1670
- tool_content[:hint] = "Keep old_string unchanged. Simply re-read the file if needed and retry with the exact same old_string."
1659
+ tool_content = {
1660
+ error: message,
1661
+ user_feedback: user_feedback
1662
+ }
1671
1663
  end
1672
1664
 
1673
1665
  {
data/lib/clacky/cli.rb CHANGED
@@ -62,6 +62,13 @@ module Clacky
62
62
  end
63
63
  config = Clacky::Config.load
64
64
 
65
+ # Show message when using ClaudeCode environment variables
66
+ if config.config_source == "claude_code"
67
+ say "🔑 Using API key from ClaudeCode environment variables", :cyan
68
+ say " (#{config.base_url})", :white
69
+ say ""
70
+ end
71
+
65
72
  unless config.api_key
66
73
  say "Error: API key not found. Please run 'clacky config set' first.", :red
67
74
  exit 1
@@ -750,14 +757,14 @@ module Clacky
750
757
  # Save final session state before exit
751
758
  if session_manager && agent.total_tasks > 0
752
759
  session_data = agent.to_session_data(status: :exited)
753
- session_manager.save(session_data)
760
+ saved_path = session_manager.save(session_data)
754
761
 
755
762
  # Show session saved message in output area (before stopping UI)
756
763
  session_id = session_data[:session_id][0..7]
757
764
  ui_controller.append_output("")
758
765
  ui_controller.append_output("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
759
766
  ui_controller.append_output("")
760
- ui_controller.append_output("Session saved: #{session_id}")
767
+ ui_controller.append_output("Session saved: #{saved_path}")
761
768
  ui_controller.append_output("Tasks completed: #{agent.total_tasks}")
762
769
  ui_controller.append_output("Total cost: $#{agent.total_cost.round(4)}")
763
770
  ui_controller.append_output("")
@@ -868,11 +875,6 @@ module Clacky
868
875
  if session_manager && agent.total_tasks > 0
869
876
  session_manager.save(agent.to_session_data)
870
877
  end
871
-
872
- # Show goodbye message
873
- say "\n👋 Goodbye! Session stats:", :green
874
- say " Tasks completed: #{agent.total_tasks}", :cyan
875
- say " Total cost: $#{agent.total_cost.round(4)}", :cyan
876
878
  end
877
879
 
878
880
  end