samagotchi 0.102.0 → 0.104.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 (106) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +93 -1
  3. data/bin/chi +60 -191
  4. data/docs/architecture.md +67 -1
  5. data/docs/cli.md +190 -9
  6. data/docs/configuration.md +7 -1
  7. data/docs/guardrails.md +4 -2
  8. data/docs/internals/context-telemetry.md +6 -2
  9. data/docs/internals/engine.md +5 -2
  10. data/docs/internals/llm-context-forget.md +11 -1
  11. data/docs/internals/participants.md +137 -0
  12. data/docs/internals/remote-sessions.md +429 -0
  13. data/docs/internals/working-set.md +95 -11
  14. data/docs/plugins.md +33 -3
  15. data/docs/sessions.md +16 -7
  16. data/docs/sub-agent.md +16 -0
  17. data/docs/testing.md +68 -4
  18. data/lib/samagotchi/answer_command.rb +27 -25
  19. data/lib/samagotchi/bridge.rb +31 -7
  20. data/lib/samagotchi/bridge_client/event_stream.rb +86 -12
  21. data/lib/samagotchi/bridge_client/stream_request.rb +77 -0
  22. data/lib/samagotchi/bridge_client.rb +26 -39
  23. data/lib/samagotchi/bundles/claude-peer/manifest.yml +2 -2
  24. data/lib/samagotchi/bundles/claude-peer/scripts/pair +30 -1
  25. data/lib/samagotchi/bundles/codex-peer/manifest.yml +2 -2
  26. data/lib/samagotchi/bundles/codex-peer/scripts/pair +49 -4
  27. data/lib/samagotchi/bundles/guardrails/guardrails/rules.yml +7 -4
  28. data/lib/samagotchi/bundles/guardrails/manifest.yml +1 -1
  29. data/lib/samagotchi/bundles/system/manifest.yml +1 -1
  30. data/lib/samagotchi/chi_invocation.rb +40 -0
  31. data/lib/samagotchi/cli/command.rb +3 -2
  32. data/lib/samagotchi/cli/flags.rb +5 -0
  33. data/lib/samagotchi/cli/parent_wait.rb +22 -13
  34. data/lib/samagotchi/context_command.rb +80 -73
  35. data/lib/samagotchi/context_status.rb +15 -2
  36. data/lib/samagotchi/engine.rb +28 -14
  37. data/lib/samagotchi/guardrail_wiring.rb +7 -1
  38. data/lib/samagotchi/idle_recap.rb +8 -2
  39. data/lib/samagotchi/idle_scheduler.rb +34 -9
  40. data/lib/samagotchi/kernel_loop.rb +21 -2
  41. data/lib/samagotchi/launch_mode.rb +26 -0
  42. data/lib/samagotchi/llm/chat_loop.rb +8 -1
  43. data/lib/samagotchi/llm_context_forget.rb +13 -6
  44. data/lib/samagotchi/note_command.rb +8 -7
  45. data/lib/samagotchi/owner_lock.rb +65 -5
  46. data/lib/samagotchi/parent_report.rb +55 -43
  47. data/lib/samagotchi/participants.rb +122 -0
  48. data/lib/samagotchi/remote_attach_command.rb +119 -0
  49. data/lib/samagotchi/remote_command.rb +170 -0
  50. data/lib/samagotchi/remotes.rb +130 -0
  51. data/lib/samagotchi/run_options.rb +245 -0
  52. data/lib/samagotchi/send_command/busy.rb +58 -0
  53. data/lib/samagotchi/send_command/parent_gate.rb +23 -10
  54. data/lib/samagotchi/send_command/wait_target.rb +16 -3
  55. data/lib/samagotchi/send_command.rb +173 -108
  56. data/lib/samagotchi/session.rb +38 -9
  57. data/lib/samagotchi/session_access/contract.rb +167 -0
  58. data/lib/samagotchi/session_access/dispatch.rb +152 -0
  59. data/lib/samagotchi/session_access/http_transport.rb +109 -0
  60. data/lib/samagotchi/session_access/local.rb +400 -0
  61. data/lib/samagotchi/session_access/remote.rb +734 -0
  62. data/lib/samagotchi/session_access/web_bridge_client.rb +236 -0
  63. data/lib/samagotchi/session_access.rb +223 -0
  64. data/lib/samagotchi/session_archive_command.rb +9 -5
  65. data/lib/samagotchi/session_commands.rb +20 -15
  66. data/lib/samagotchi/session_continue.rb +1 -1
  67. data/lib/samagotchi/session_delete_command.rb +8 -4
  68. data/lib/samagotchi/session_inbox.rb +18 -9
  69. data/lib/samagotchi/session_manager.rb +27 -6
  70. data/lib/samagotchi/session_setup.rb +11 -6
  71. data/lib/samagotchi/sessions_command.rb +36 -14
  72. data/lib/samagotchi/share_command.rb +174 -0
  73. data/lib/samagotchi/terminal_ui/attach_launcher.rb +66 -17
  74. data/lib/samagotchi/terminal_ui/attach_link.rb +114 -0
  75. data/lib/samagotchi/terminal_ui/attached_loop.rb +155 -87
  76. data/lib/samagotchi/terminal_ui/formatting.rb +13 -1
  77. data/lib/samagotchi/terminal_ui/local_link.rb +135 -0
  78. data/lib/samagotchi/terminal_ui/remote_connector.rb +66 -0
  79. data/lib/samagotchi/terminal_ui/remote_link.rb +245 -0
  80. data/lib/samagotchi/terminal_ui/version_lines.rb +28 -3
  81. data/lib/samagotchi/terminal_ui.rb +6 -3
  82. data/lib/samagotchi/testing/waiting.rb +92 -9
  83. data/lib/samagotchi/title_command.rb +9 -11
  84. data/lib/samagotchi/tools/task_runtime.rb +17 -3
  85. data/lib/samagotchi/version.rb +1 -1
  86. data/lib/samagotchi/web/app.rb +530 -126
  87. data/lib/samagotchi/web/grants.rb +302 -0
  88. data/lib/samagotchi/web/participant_access.rb +286 -0
  89. data/lib/samagotchi/web/principal.rb +29 -0
  90. data/lib/samagotchi/web/public/data.js +3 -2
  91. data/lib/samagotchi/web/public/index.html +20 -4
  92. data/lib/samagotchi/web/public/stage_frame.js +7 -2
  93. data/lib/samagotchi/web/public/stage_view.js +3 -2
  94. data/lib/samagotchi/web/public/stream_handlers.js +3 -1
  95. data/lib/samagotchi/web/public/working_set.js +159 -28
  96. data/lib/samagotchi/web/public/working_set_rail.js +39 -12
  97. data/lib/samagotchi/web/public/working_set_view.js +91 -33
  98. data/lib/samagotchi/web/server.rb +3 -1
  99. data/lib/samagotchi/web/session_access_routes.rb +459 -0
  100. data/lib/samagotchi/worker.rb +26 -5
  101. data/lib/samagotchi/worker_sidecar.rb +12 -5
  102. data/lib/samagotchi/working_set.rb +88 -14
  103. data/lib/samagotchi/working_set_command.rb +133 -30
  104. data/lib/samagotchi/working_set_pin.rb +34 -0
  105. data/lib/samagotchi/working_set_steer.rb +191 -27
  106. metadata +28 -1
@@ -3,12 +3,13 @@
3
3
  module Samagotchi
4
4
  # /title, the session's own name (Session#title): with no argument, the
5
5
  # title and what shows without one; `/title TEXT` names the session
6
- # (whitespace collapsed, cut at 80 characters as a preview is), saved at
7
- # once; `/title --clear` drops it, and the lists show the first message
8
- # again. Anyone who may send the session a command may name it (a parent
9
- # agent its delegates too). It runs mid-turn as well (anytime): the save
10
- # takes the session's lock and writes a running turn's checkpoint, as a
11
- # turn's own saves do.
6
+ # (whitespace collapsed, cut at 80 characters as a preview is);
7
+ # `/title --clear` drops it, and the lists show the first message again.
8
+ # Anyone who may send the session a command may name it (a parent agent
9
+ # its delegates too). It doesn't save: its host saves a changed result at
10
+ # once (Worker, the REPL). It runs mid-turn as well (anytime): the
11
+ # worker's save takes the session's lock and writes a running turn's
12
+ # checkpoint, as a turn's own saves do.
12
13
  class TitleCommand
13
14
  NAME = "/title"
14
15
  CLEAR = "--clear"
@@ -17,10 +18,8 @@ module Samagotchi
17
18
  LIMIT = 80
18
19
 
19
20
  # @param engine [Engine] #session
20
- # @param save [#call] saves the session after a change
21
- def initialize(engine:, save:)
21
+ def initialize(engine:)
22
22
  @engine = engine
23
- @save = save
24
23
  end
25
24
 
26
25
  # @param args [String] what follows /title
@@ -42,9 +41,8 @@ module Samagotchi
42
41
  session.title = title
43
42
  # The command itself as the session's first line (chi send --new
44
43
  # "/title X", a web first message) became its preview: it goes, and
45
- # the save derives the preview from the first user message again.
44
+ # the host's save derives the preview from the first user message again.
46
45
  session.first_preview = "" if session.first_preview.to_s.start_with?(NAME)
47
- @save.call(session)
48
46
  [listing(session), true, :ok]
49
47
  end
50
48
 
@@ -99,9 +99,10 @@ module Samagotchi
99
99
  # status. Only while this chi runs. A record a refresh finished in
100
100
  # between (failed, no exit code) is corrected; a stopped task (its
101
101
  # stop flag on disk) is left as task_stop records it.
102
- # The thread is named EXIT_STATUS_THREAD (a spec joins them before it
103
- # removes the tasks' folder) here, before it returns: named from
104
- # inside, a thread not yet scheduled was missed by that join.
102
+ # The thread is named EXIT_STATUS_THREAD (a spec joins them with
103
+ # #quiesce! before it removes the tasks' folder) here, before it
104
+ # returns: named from inside, a thread not yet scheduled was missed by
105
+ # that join.
105
106
  # @return [Thread]
106
107
  def record_exit_status(waiter, path, task_id:)
107
108
  # Absolute now: safe against a later chdir.
@@ -132,6 +133,19 @@ module Samagotchi
132
133
  # record_exit_status's threads' name.
133
134
  EXIT_STATUS_THREAD = "task_exit_status"
134
135
 
136
+ # Joins every live EXIT_STATUS_THREAD, for up to +timeout+ s in all: a
137
+ # spec calls it (with_task_dir) after stopping its tasks and before it
138
+ # removes their folder, which a recorder may still write into. chi
139
+ # itself doesn't call it.
140
+ # @return [Array<Thread>] the ones still alive after +timeout+ (empty
141
+ # when quiet)
142
+ def quiesce!(timeout: 5)
143
+ deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + timeout
144
+ threads = Thread.list.select { |thread| thread.name == EXIT_STATUS_THREAD && thread != Thread.current }
145
+ threads.each { |thread| thread.join([deadline - Process.clock_gettime(Process::CLOCK_MONOTONIC), 0].max) }
146
+ threads.select(&:alive?)
147
+ end
148
+
135
149
  # Reasons a refresh finishes a record with when it read no exit code.
136
150
  MISSING_CODE_REASONS = ["process_ended_without_exit_code", NOT_CHIS_PROCESS].freeze
137
151
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Samagotchi
4
- VERSION = "0.102.0"
4
+ VERSION = "0.104.0"
5
5
  # Sent as the User-Agent of every HTTP request chi makes.
6
6
  USER_AGENT = "chi/#{VERSION}"
7
7
  end