samagotchi 0.3.0 → 0.5.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.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +162 -1
  3. data/README.md +29 -2
  4. data/bin/chi +60 -69
  5. data/docs/cli.md +211 -77
  6. data/docs/configuration.md +118 -21
  7. data/docs/desktop.md +39 -4
  8. data/docs/guardrails.md +11 -0
  9. data/docs/hooks.md +89 -7
  10. data/docs/memory.md +40 -0
  11. data/docs/plugins.md +50 -0
  12. data/docs/releasing.md +15 -12
  13. data/docs/sessions.md +20 -18
  14. data/lib/samagotchi/bootstrap/config_writer.rb +1 -2
  15. data/lib/samagotchi/bridge/sse_writer.rb +0 -3
  16. data/lib/samagotchi/bridge/turn_accumulator.rb +2 -0
  17. data/lib/samagotchi/bridge.rb +20 -12
  18. data/lib/samagotchi/bundles/skills/manifest.yml +10 -0
  19. data/lib/samagotchi/bundles/skills/plugin.rb +419 -0
  20. data/lib/samagotchi/bundles/source-links/hooks/source_links.rb +178 -5
  21. data/lib/samagotchi/bundles/source-links/manifest.yml +3 -3
  22. data/lib/samagotchi/bundles/source-links/source_links.md +1 -1
  23. data/lib/samagotchi/bundles/system/config_modification_protocol.md +9 -10
  24. data/lib/samagotchi/bundles/system/delegated.md +6 -7
  25. data/lib/samagotchi/bundles/system/identity.md +5 -0
  26. data/lib/samagotchi/bundles/system/manifest.yml +6 -6
  27. data/lib/samagotchi/bundles/system/memory_guide.md +26 -0
  28. data/lib/samagotchi/bundles/system/self_map.md +2 -1
  29. data/lib/samagotchi/client.rb +25 -26
  30. data/lib/samagotchi/commands/registry.rb +8 -0
  31. data/lib/samagotchi/config.rb +97 -113
  32. data/lib/samagotchi/desktop/macos/App.swift +12 -8
  33. data/lib/samagotchi/desktop/macos/ChiRunner.swift +4 -2
  34. data/lib/samagotchi/desktop/macos/Images.swift +113 -0
  35. data/lib/samagotchi/desktop/macos/Info.plist.erb +6 -0
  36. data/lib/samagotchi/desktop/macos/Panel.swift +112 -9
  37. data/lib/samagotchi/desktop/macos.rb +59 -8
  38. data/lib/samagotchi/desktop_command.rb +6 -3
  39. data/lib/samagotchi/edit_preview.rb +82 -0
  40. data/lib/samagotchi/engine.rb +236 -443
  41. data/lib/samagotchi/gem_update.rb +89 -0
  42. data/lib/samagotchi/guardrails/approval.rb +26 -4
  43. data/lib/samagotchi/guardrails/load_failures.rb +9 -3
  44. data/lib/samagotchi/host_registry.rb +8 -12
  45. data/lib/samagotchi/idle_client.rb +24 -15
  46. data/lib/samagotchi/idle_reminders.rb +2 -2
  47. data/lib/samagotchi/image_store.rb +10 -6
  48. data/lib/samagotchi/kernel_loop.rb +59 -123
  49. data/lib/samagotchi/live_versions.rb +65 -0
  50. data/lib/samagotchi/llm/api_key.rb +41 -0
  51. data/lib/samagotchi/llm/chat_loop.rb +77 -13
  52. data/lib/samagotchi/llm/errors.rb +38 -7
  53. data/lib/samagotchi/llm/http.rb +19 -22
  54. data/lib/samagotchi/llm/openai_chat.rb +22 -26
  55. data/lib/samagotchi/memory_bundle/installer.rb +65 -63
  56. data/lib/samagotchi/memory_bundle/provenance.rb +51 -12
  57. data/lib/samagotchi/memory_bundle/shipped_update.rb +157 -0
  58. data/lib/samagotchi/memory_bundle/status.rb +4 -1
  59. data/lib/samagotchi/memory_bundle/system_bundle.rb +81 -53
  60. data/lib/samagotchi/model_profile.rb +27 -10
  61. data/lib/samagotchi/note_command.rb +2 -1
  62. data/lib/samagotchi/prompt.rb +4 -2
  63. data/lib/samagotchi/reminder_store.rb +1 -9
  64. data/lib/samagotchi/reply_wait.rb +48 -4
  65. data/lib/samagotchi/self_report.rb +37 -5
  66. data/lib/samagotchi/send_command.rb +190 -17
  67. data/lib/samagotchi/session.rb +4 -2
  68. data/lib/samagotchi/session_commands.rb +38 -8
  69. data/lib/samagotchi/session_manager.rb +19 -53
  70. data/lib/samagotchi/system_prompt.rb +403 -0
  71. data/lib/samagotchi/terminal_ui/attach_launcher.rb +5 -3
  72. data/lib/samagotchi/terminal_ui/attached_loop.rb +141 -108
  73. data/lib/samagotchi/terminal_ui/attached_view.rb +27 -12
  74. data/lib/samagotchi/terminal_ui/event_renderer.rb +29 -8
  75. data/lib/samagotchi/terminal_ui/formatting.rb +41 -22
  76. data/lib/samagotchi/terminal_ui/input_support.rb +7 -23
  77. data/lib/samagotchi/terminal_ui/plain_surface.rb +13 -7
  78. data/lib/samagotchi/terminal_ui/question_prompt.rb +35 -0
  79. data/lib/samagotchi/terminal_ui/status_row.rb +81 -0
  80. data/lib/samagotchi/terminal_ui/surface.rb +1 -1
  81. data/lib/samagotchi/terminal_ui.rb +142 -923
  82. data/lib/samagotchi/text_diff.rb +181 -0
  83. data/lib/samagotchi/thinking.rb +126 -0
  84. data/lib/samagotchi/tool_activity.rb +52 -2
  85. data/lib/samagotchi/tool_runner.rb +37 -1
  86. data/lib/samagotchi/tools/ask_user_question.rb +41 -33
  87. data/lib/samagotchi/tools/edit.rb +23 -9
  88. data/lib/samagotchi/tools/execute.rb +3 -3
  89. data/lib/samagotchi/tools/output_guardrails.rb +8 -7
  90. data/lib/samagotchi/tools/read.rb +4 -4
  91. data/lib/samagotchi/tools/write.rb +4 -0
  92. data/lib/samagotchi/turn_flow.rb +12 -2
  93. data/lib/samagotchi/update_command.rb +309 -0
  94. data/lib/samagotchi/update_hint.rb +59 -0
  95. data/lib/samagotchi/version.rb +1 -1
  96. data/lib/samagotchi/vision_support.rb +6 -4
  97. data/lib/samagotchi/web/app.rb +173 -38
  98. data/lib/samagotchi/web/lan.rb +99 -0
  99. data/lib/samagotchi/web/message_parts.rb +19 -10
  100. data/lib/samagotchi/web/public/activity.js +10 -0
  101. data/lib/samagotchi/web/public/app.js +135 -78
  102. data/lib/samagotchi/web/public/chat_view.js +8 -1
  103. data/lib/samagotchi/web/public/data.js +2 -0
  104. data/lib/samagotchi/web/public/diff_view.js +58 -0
  105. data/lib/samagotchi/web/public/index.html +185 -18
  106. data/lib/samagotchi/web/public/model_pick.js +136 -0
  107. data/lib/samagotchi/web/public/model_picker.js +224 -0
  108. data/lib/samagotchi/web/public/notify.js +10 -0
  109. data/lib/samagotchi/web/public/question_card.js +3 -1
  110. data/lib/samagotchi/web/public/stage_model.js +110 -0
  111. data/lib/samagotchi/web/public/stage_view.js +580 -0
  112. data/lib/samagotchi/web/public/timing.js +6 -2
  113. data/lib/samagotchi/web/public/turn_events.js +38 -10
  114. data/lib/samagotchi/web/public/turn_model.js +11 -3
  115. data/lib/samagotchi/web/public/turn_view.js +76 -20
  116. data/lib/samagotchi/web/qr.rb +40 -0
  117. data/lib/samagotchi/web/server.rb +101 -11
  118. data/lib/samagotchi/web/token.rb +97 -0
  119. data/lib/samagotchi/worker.rb +5 -4
  120. metadata +38 -3
  121. data/lib/samagotchi/terminal_ui/legacy_surface.rb +0 -111
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: samagotchi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Dedov
@@ -93,6 +93,20 @@ dependencies:
93
93
  - - ">="
94
94
  - !ruby/object:Gem::Version
95
95
  version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: rqrcode_core
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '2.0'
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '2.0'
96
110
  description: chi is an agent harness for local and OpenAI-compatible models (llama.cpp,
97
111
  mlx, oMLX, hosted APIs). It runs sessions in a terminal REPL or in background workers
98
112
  you can attach to from the terminal and a web UI, keeps memories in plain files
@@ -154,6 +168,8 @@ files:
154
168
  - lib/samagotchi/bundles/loop-guard/plugin.rb
155
169
  - lib/samagotchi/bundles/mcp/manifest.yml
156
170
  - lib/samagotchi/bundles/mcp/plugin.rb
171
+ - lib/samagotchi/bundles/skills/manifest.yml
172
+ - lib/samagotchi/bundles/skills/plugin.rb
157
173
  - lib/samagotchi/bundles/source-links/hooks/source_links.rb
158
174
  - lib/samagotchi/bundles/source-links/manifest.yml
159
175
  - lib/samagotchi/bundles/source-links/source_links.md
@@ -177,11 +193,14 @@ files:
177
193
  - lib/samagotchi/desktop/macos/App.swift
178
194
  - lib/samagotchi/desktop/macos/ChiRunner.swift
179
195
  - lib/samagotchi/desktop/macos/Hotkey.swift
196
+ - lib/samagotchi/desktop/macos/Images.swift
180
197
  - lib/samagotchi/desktop/macos/Info.plist.erb
181
198
  - lib/samagotchi/desktop/macos/Panel.swift
182
199
  - lib/samagotchi/desktop_command.rb
200
+ - lib/samagotchi/edit_preview.rb
183
201
  - lib/samagotchi/empty_answer_retry.rb
184
202
  - lib/samagotchi/engine.rb
203
+ - lib/samagotchi/gem_update.rb
185
204
  - lib/samagotchi/guardrails.rb
186
205
  - lib/samagotchi/guardrails/approval.rb
187
206
  - lib/samagotchi/guardrails/approvals.rb
@@ -206,6 +225,8 @@ files:
206
225
  - lib/samagotchi/installed_gem.rb
207
226
  - lib/samagotchi/kernel_loop.rb
208
227
  - lib/samagotchi/launch_mode.rb
228
+ - lib/samagotchi/live_versions.rb
229
+ - lib/samagotchi/llm/api_key.rb
209
230
  - lib/samagotchi/llm/backend.rb
210
231
  - lib/samagotchi/llm/chat_loop.rb
211
232
  - lib/samagotchi/llm/errors.rb
@@ -228,6 +249,7 @@ files:
228
249
  - lib/samagotchi/memory_bundle/merger.rb
229
250
  - lib/samagotchi/memory_bundle/placeholder.rb
230
251
  - lib/samagotchi/memory_bundle/provenance.rb
252
+ - lib/samagotchi/memory_bundle/shipped_update.rb
231
253
  - lib/samagotchi/memory_bundle/source.rb
232
254
  - lib/samagotchi/memory_bundle/status.rb
233
255
  - lib/samagotchi/memory_bundle/system_bundle.rb
@@ -265,6 +287,7 @@ files:
265
287
  - lib/samagotchi/session_metrics.rb
266
288
  - lib/samagotchi/session_observer.rb
267
289
  - lib/samagotchi/steer.rb
290
+ - lib/samagotchi/system_prompt.rb
268
291
  - lib/samagotchi/terminal_ui.rb
269
292
  - lib/samagotchi/terminal_ui/attach_launcher.rb
270
293
  - lib/samagotchi/terminal_ui/attached_loop.rb
@@ -273,7 +296,6 @@ files:
273
296
  - lib/samagotchi/terminal_ui/formatting.rb
274
297
  - lib/samagotchi/terminal_ui/image_input.rb
275
298
  - lib/samagotchi/terminal_ui/input_support.rb
276
- - lib/samagotchi/terminal_ui/legacy_surface.rb
277
299
  - lib/samagotchi/terminal_ui/line_reader.rb
278
300
  - lib/samagotchi/terminal_ui/live_region.rb
279
301
  - lib/samagotchi/terminal_ui/plain_surface.rb
@@ -282,8 +304,11 @@ files:
282
304
  - lib/samagotchi/terminal_ui/reline_seam.rb
283
305
  - lib/samagotchi/terminal_ui/repl_input.rb
284
306
  - lib/samagotchi/terminal_ui/screen.rb
307
+ - lib/samagotchi/terminal_ui/status_row.rb
285
308
  - lib/samagotchi/terminal_ui/surface.rb
286
309
  - lib/samagotchi/terminal_ui/thinking_line.rb
310
+ - lib/samagotchi/text_diff.rb
311
+ - lib/samagotchi/thinking.rb
287
312
  - lib/samagotchi/thinking_ticker.rb
288
313
  - lib/samagotchi/thought_stream_splitter.rb
289
314
  - lib/samagotchi/token_usage.rb
@@ -321,10 +346,13 @@ files:
321
346
  - lib/samagotchi/turn_flow.rb
322
347
  - lib/samagotchi/turn_note.rb
323
348
  - lib/samagotchi/turn_tally.rb
349
+ - lib/samagotchi/update_command.rb
350
+ - lib/samagotchi/update_hint.rb
324
351
  - lib/samagotchi/version.rb
325
352
  - lib/samagotchi/vision_context.rb
326
353
  - lib/samagotchi/vision_support.rb
327
354
  - lib/samagotchi/web/app.rb
355
+ - lib/samagotchi/web/lan.rb
328
356
  - lib/samagotchi/web/markdown_renderer.rb
329
357
  - lib/samagotchi/web/message_parts.rb
330
358
  - lib/samagotchi/web/public/activity.js
@@ -339,12 +367,14 @@ files:
339
367
  - lib/samagotchi/web/public/copy.js
340
368
  - lib/samagotchi/web/public/ctx.js
341
369
  - lib/samagotchi/web/public/data.js
370
+ - lib/samagotchi/web/public/diff_view.js
342
371
  - lib/samagotchi/web/public/format.js
343
372
  - lib/samagotchi/web/public/hold.js
344
373
  - lib/samagotchi/web/public/images.js
345
374
  - lib/samagotchi/web/public/index.html
346
375
  - lib/samagotchi/web/public/init_row.js
347
376
  - lib/samagotchi/web/public/model_pick.js
377
+ - lib/samagotchi/web/public/model_picker.js
348
378
  - lib/samagotchi/web/public/notify.js
349
379
  - lib/samagotchi/web/public/question_card.js
350
380
  - lib/samagotchi/web/public/route.js
@@ -352,6 +382,8 @@ files:
352
382
  - lib/samagotchi/web/public/scroll.js
353
383
  - lib/samagotchi/web/public/sentences.js
354
384
  - lib/samagotchi/web/public/sessions_list.js
385
+ - lib/samagotchi/web/public/stage_model.js
386
+ - lib/samagotchi/web/public/stage_view.js
355
387
  - lib/samagotchi/web/public/strip.js
356
388
  - lib/samagotchi/web/public/tally.js
357
389
  - lib/samagotchi/web/public/thinking_ticker.js
@@ -359,9 +391,11 @@ files:
359
391
  - lib/samagotchi/web/public/turn_events.js
360
392
  - lib/samagotchi/web/public/turn_model.js
361
393
  - lib/samagotchi/web/public/turn_view.js
394
+ - lib/samagotchi/web/qr.rb
362
395
  - lib/samagotchi/web/server.rb
363
396
  - lib/samagotchi/web/session_hub.rb
364
397
  - lib/samagotchi/web/session_summary.rb
398
+ - lib/samagotchi/web/token.rb
365
399
  - lib/samagotchi/worker.rb
366
400
  - lib/samagotchi/worker_idle_exit.rb
367
401
  homepage: https://github.com/dm1try/samagotchi
@@ -389,5 +423,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
389
423
  requirements: []
390
424
  rubygems_version: 3.6.9
391
425
  specification_version: 4
392
- summary: 'chi: a local-first coding agent with memory, sessions and a web UI'
426
+ summary: 'chi: a local-first, human-in-the-loop agent harness that learns memories
427
+ and skills as you work'
393
428
  test_files: []
@@ -1,111 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "io/console"
4
- require_relative "surface"
5
-
6
- module Samagotchi
7
- class TerminalUI
8
- # The REPL's Surface before the live region: plain output where the
9
- # cursor is. Only the activity slot is live. It redraws in place by
10
- # moving back up over the rows it drew last (ESC[nA), which works only
11
- # while nothing else writes below it. The editor slot prints a prompt
12
- # for a plain read, and clearing it erases the line Reline drew. The other
13
- # slots just print their rows, except status rows set together with the
14
- # activity rows (#set_slots): those are the activity block's last rows.
15
- class LegacySurface
16
- include Surface
17
-
18
- # @param out [IO, nil] nil writes to $stdout as it is at each write
19
- # (specs swap it after the UI is built)
20
- def initialize(out: nil)
21
- @out = out
22
- @activity_shown = false
23
- @activity_rows = 0
24
- end
25
-
26
- def commit(text)
27
- out.puts(text)
28
- end
29
-
30
- def set_slot(name, rows)
31
- check_slot!(name)
32
- case name
33
- when :activity then redraw_activity(rows)
34
- when :editor
35
- out.print(rows.join("\n"))
36
- out.flush
37
- else lay_out(rows, width: columns).each { |row| out.puts(row) }
38
- end
39
- end
40
-
41
- def set_slots(**rows_by_slot)
42
- return super unless rows_by_slot.key?(:activity)
43
-
44
- activity = rows_by_slot.delete(:activity)
45
- status = rows_by_slot.delete(:status)
46
- set_slot(:activity, Array(activity) + Array(status))
47
- super(**rows_by_slot)
48
- end
49
-
50
- def clear_slot(name)
51
- check_slot!(name)
52
- case name
53
- when :activity then erase_activity
54
- when :editor
55
- out.print("\r\e[2K")
56
- out.flush
57
- true
58
- else false
59
- end
60
- end
61
-
62
- private
63
-
64
- def out = @out || $stdout
65
-
66
- def columns
67
- IO.console&.winsize&.last || 80
68
- rescue StandardError
69
- 80
70
- end
71
-
72
- # Pad to the taller of the old and new heights, so rows left over from
73
- # a taller frame are blanked.
74
- def redraw_activity(rows)
75
- move_to_activity_origin
76
- row_count = [@activity_rows, rows.length].max
77
- padded = rows + Array.new(row_count - rows.length, "")
78
- out.print(padded.map { |text| "#{text}\e[0K" }.join("\n"))
79
- out.flush
80
- @activity_shown = true
81
- @activity_rows = row_count
82
- end
83
-
84
- def move_to_activity_origin
85
- return unless @activity_shown
86
-
87
- out.print("\e[#{@activity_rows - 1}A") if @activity_rows > 1
88
- out.print("\r")
89
- end
90
-
91
- def erase_activity
92
- return false unless @activity_shown
93
-
94
- row_count = @activity_rows
95
- row_count = 1 if row_count <= 0
96
- out.print("\e[#{row_count - 1}A") if row_count > 1
97
- out.print("\r")
98
- row_count.times do |index|
99
- out.print("\e[0K")
100
- out.print("\n") if index < row_count - 1
101
- end
102
- out.print("\e[#{row_count - 1}A") if row_count > 1
103
- out.print("\r")
104
- out.flush
105
- @activity_shown = false
106
- @activity_rows = 0
107
- true
108
- end
109
- end
110
- end
111
- end