samagotchi 0.155.0 → 0.157.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 (234) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +57 -1
  3. data/bin/chi +2 -1
  4. data/docs/architecture.md +22 -13
  5. data/docs/bundles.md +3 -1
  6. data/docs/cli.md +9 -8
  7. data/docs/configuration.md +36 -4
  8. data/docs/guardrails.md +9 -5
  9. data/docs/hooks.md +11 -5
  10. data/docs/internals/anthropic.md +1 -1
  11. data/docs/internals/attached-context.md +3 -2
  12. data/docs/internals/background-tasks.md +1 -1
  13. data/docs/internals/bridge.md +83 -6
  14. data/docs/internals/bundles.md +28 -18
  15. data/docs/internals/context-telemetry.md +4 -3
  16. data/docs/internals/engine.md +641 -937
  17. data/docs/internals/llm-context-forget.md +8 -3
  18. data/docs/internals/objectives.md +2 -2
  19. data/docs/internals/participants.md +3 -2
  20. data/docs/internals/prompt-caching.md +4 -1
  21. data/docs/internals/remote-sessions.md +8 -3
  22. data/docs/internals/web-frontend.md +3 -2
  23. data/docs/internals/working-set.md +2 -2
  24. data/docs/memory.md +13 -2
  25. data/docs/plugins.md +35 -2
  26. data/docs/sessions.md +11 -11
  27. data/docs/sub-agent.md +17 -2
  28. data/docs/system-one.md +3 -2
  29. data/docs/testing.md +53 -2
  30. data/lib/samagotchi/answer_command.rb +2 -1
  31. data/lib/samagotchi/archive_store.rb +4 -3
  32. data/lib/samagotchi/bootstrap/config_writer.rb +1 -1
  33. data/lib/samagotchi/bootstrap_command.rb +3 -2
  34. data/lib/samagotchi/bridge/card_places.rb +10 -4
  35. data/lib/samagotchi/bridge/card_store.rb +3 -0
  36. data/lib/samagotchi/bridge/turn_accumulator.rb +109 -9
  37. data/lib/samagotchi/bridge/turn_drawings.rb +265 -0
  38. data/lib/samagotchi/bridge.rb +31 -6
  39. data/lib/samagotchi/broadcast/recipients.rb +8 -8
  40. data/lib/samagotchi/broadcast/triage_model.rb +1 -1
  41. data/lib/samagotchi/broadcast_command.rb +3 -3
  42. data/lib/samagotchi/bundle_command/check.rb +18 -0
  43. data/lib/samagotchi/bundle_command/try/sandbox.rb +2 -2
  44. data/lib/samagotchi/bundle_command/try/trace.rb +1 -1
  45. data/lib/samagotchi/bundle_command.rb +5 -2
  46. data/lib/samagotchi/bundles/known-names/manifest.yml +4 -7
  47. data/lib/samagotchi/bundles/known-names/{hooks/known_names.rb → plugin.rb} +17 -0
  48. data/lib/samagotchi/bundles/source-links/manifest.yml +4 -7
  49. data/lib/samagotchi/bundles/source-links/{hooks/source_links.rb → plugin.rb} +23 -4
  50. data/lib/samagotchi/bundles/system/config_modification_protocol.md +2 -2
  51. data/lib/samagotchi/bundles/system/manifest.yml +3 -3
  52. data/lib/samagotchi/bundles/system/memory_guide.md +1 -1
  53. data/lib/samagotchi/child_move.rb +13 -57
  54. data/lib/samagotchi/child_reports.rb +2 -2
  55. data/lib/samagotchi/children_status.rb +15 -21
  56. data/lib/samagotchi/cli/parent_wait.rb +9 -23
  57. data/lib/samagotchi/config.rb +20 -112
  58. data/lib/samagotchi/context_command.rb +1 -2
  59. data/lib/samagotchi/context_sources.rb +5 -4
  60. data/lib/samagotchi/context_window.rb +9 -12
  61. data/lib/samagotchi/desktop/macos.rb +1 -1
  62. data/lib/samagotchi/effective_model.rb +57 -22
  63. data/lib/samagotchi/engine/context_judge.rb +19 -11
  64. data/lib/samagotchi/engine/messages.rb +1 -1
  65. data/lib/samagotchi/engine/models.rb +5 -2
  66. data/lib/samagotchi/engine/objectives.rb +29 -11
  67. data/lib/samagotchi/engine/plugins.rb +1 -1
  68. data/lib/samagotchi/engine/recap.rb +8 -4
  69. data/lib/samagotchi/engine/side_requests.rb +21 -11
  70. data/lib/samagotchi/engine/toolkit.rb +10 -9
  71. data/lib/samagotchi/engine/turn_end.rb +1 -1
  72. data/lib/samagotchi/engine/turn_helpers.rb +7 -7
  73. data/lib/samagotchi/engine/verify.rb +1 -1
  74. data/lib/samagotchi/engine.rb +43 -12
  75. data/lib/samagotchi/events.rb +3 -2
  76. data/lib/samagotchi/extension_load.rb +6 -3
  77. data/lib/samagotchi/guardrails/targets.rb +24 -9
  78. data/lib/samagotchi/guardrails_command.rb +1 -1
  79. data/lib/samagotchi/host_address.rb +52 -0
  80. data/lib/samagotchi/host_config.rb +72 -1
  81. data/lib/samagotchi/host_model.rb +2 -6
  82. data/lib/samagotchi/host_registry.rb +58 -46
  83. data/lib/samagotchi/kernel_loop.rb +53 -124
  84. data/lib/samagotchi/llm/anthropic_wire.rb +2 -2
  85. data/lib/samagotchi/llm/chat_loop.rb +40 -21
  86. data/lib/samagotchi/llm/native_backend.rb +1 -1
  87. data/lib/samagotchi/llm_context_apply.rb +54 -1
  88. data/lib/samagotchi/llm_context_notice.rb +1 -1
  89. data/lib/samagotchi/llm_context_strategy.rb +29 -67
  90. data/lib/samagotchi/llm_context_view.rb +9 -0
  91. data/lib/samagotchi/memory_bundle/asset_installer.rb +71 -76
  92. data/lib/samagotchi/memory_bundle/builder.rb +2 -1
  93. data/lib/samagotchi/memory_bundle/file_actions.rb +193 -0
  94. data/lib/samagotchi/memory_bundle/file_digest.rb +13 -0
  95. data/lib/samagotchi/memory_bundle/file_state.rb +152 -0
  96. data/lib/samagotchi/memory_bundle/installed_copy.rb +2 -1
  97. data/lib/samagotchi/memory_bundle/installed_manifest.rb +8 -1
  98. data/lib/samagotchi/memory_bundle/installer.rb +185 -169
  99. data/lib/samagotchi/memory_bundle/manifest.rb +14 -4
  100. data/lib/samagotchi/memory_bundle/merger.rb +69 -65
  101. data/lib/samagotchi/memory_bundle/plugin_ref.rb +6 -5
  102. data/lib/samagotchi/memory_bundle/profile.rb +5 -5
  103. data/lib/samagotchi/memory_bundle/provenance.rb +15 -1
  104. data/lib/samagotchi/memory_bundle/remerge.rb +25 -12
  105. data/lib/samagotchi/memory_bundle/shipped_update.rb +51 -6
  106. data/lib/samagotchi/memory_bundle/status.rb +14 -20
  107. data/lib/samagotchi/memory_bundle/system_bundle.rb +24 -6
  108. data/lib/samagotchi/memory_bundle/trash.rb +23 -8
  109. data/lib/samagotchi/memory_bundle/uninstaller.rb +16 -11
  110. data/lib/samagotchi/memory_usage.rb +1 -1
  111. data/lib/samagotchi/model_lookup.rb +75 -0
  112. data/lib/samagotchi/model_price.rb +4 -10
  113. data/lib/samagotchi/model_profile.rb +7 -6
  114. data/lib/samagotchi/model_settings.rb +37 -2
  115. data/lib/samagotchi/models_command.rb +1 -1
  116. data/lib/samagotchi/note_command.rb +2 -3
  117. data/lib/samagotchi/objectives_audit.rb +4 -3
  118. data/lib/samagotchi/participant_mode.rb +2 -1
  119. data/lib/samagotchi/participants.rb +2 -2
  120. data/lib/samagotchi/plugin/api.rb +41 -6
  121. data/lib/samagotchi/plugin/context.rb +1 -1
  122. data/lib/samagotchi/plugin/loader.rb +33 -10
  123. data/lib/samagotchi/plugin/sessions.rb +3 -6
  124. data/lib/samagotchi/plugin/tool_spec.rb +5 -3
  125. data/lib/samagotchi/project_env.rb +1 -1
  126. data/lib/samagotchi/reasoning_history.rb +14 -20
  127. data/lib/samagotchi/recap_place.rb +27 -0
  128. data/lib/samagotchi/reminder_carry.rb +1 -1
  129. data/lib/samagotchi/reply_wait/liveness.rb +38 -0
  130. data/lib/samagotchi/reply_wait/poll.rb +44 -15
  131. data/lib/samagotchi/reply_wait/target.rb +113 -0
  132. data/lib/samagotchi/reply_wait.rb +22 -2
  133. data/lib/samagotchi/reprefill_meter.rb +45 -0
  134. data/lib/samagotchi/review_command.rb +1 -1
  135. data/lib/samagotchi/sampling_settings.rb +9 -16
  136. data/lib/samagotchi/self_report.rb +36 -37
  137. data/lib/samagotchi/send_command.rb +17 -23
  138. data/lib/samagotchi/session.rb +370 -445
  139. data/lib/samagotchi/session_access/local.rb +12 -11
  140. data/lib/samagotchi/session_access/remote.rb +22 -6
  141. data/lib/samagotchi/session_archive_command.rb +2 -2
  142. data/lib/samagotchi/session_chain.rb +7 -6
  143. data/lib/samagotchi/session_continue.rb +6 -5
  144. data/lib/samagotchi/session_delete_command.rb +1 -1
  145. data/lib/samagotchi/session_field.rb +133 -0
  146. data/lib/samagotchi/session_inbox.rb +49 -1
  147. data/lib/samagotchi/session_manager/delivery.rb +254 -0
  148. data/lib/samagotchi/session_manager/emptiness.rb +139 -0
  149. data/lib/samagotchi/session_manager/lifecycle.rb +274 -0
  150. data/lib/samagotchi/session_manager/listing.rb +118 -0
  151. data/lib/samagotchi/session_manager/removal.rb +190 -0
  152. data/lib/samagotchi/session_manager/spawn.rb +242 -0
  153. data/lib/samagotchi/session_manager/worker_command.rb +157 -0
  154. data/lib/samagotchi/session_manager.rb +28 -1541
  155. data/lib/samagotchi/session_metrics.rb +8 -5
  156. data/lib/samagotchi/session_paths.rb +57 -0
  157. data/lib/samagotchi/session_retention.rb +2 -2
  158. data/lib/samagotchi/session_row.rb +200 -0
  159. data/lib/samagotchi/session_setup.rb +15 -12
  160. data/lib/samagotchi/sessions_command.rb +11 -129
  161. data/lib/samagotchi/share_command.rb +1 -1
  162. data/lib/samagotchi/starting_marker.rb +65 -0
  163. data/lib/samagotchi/steer_cut_after.rb +7 -14
  164. data/lib/samagotchi/system_one/recorder.rb +49 -0
  165. data/lib/samagotchi/terminal_ui/attached_loop.rb +6 -26
  166. data/lib/samagotchi/terminal_ui/exit_lines.rb +1 -1
  167. data/lib/samagotchi/terminal_ui/join_replay.rb +86 -8
  168. data/lib/samagotchi/terminal_ui/local_link.rb +2 -2
  169. data/lib/samagotchi/terminal_ui.rb +5 -7
  170. data/lib/samagotchi/testing/install.rb +2 -1
  171. data/lib/samagotchi/testing/sessions.rb +1 -1
  172. data/lib/samagotchi/thinking.rb +16 -21
  173. data/lib/samagotchi/token_usage.rb +1 -1
  174. data/lib/samagotchi/tool_activity.rb +10 -4
  175. data/lib/samagotchi/tool_declarations.rb +2 -2
  176. data/lib/samagotchi/tool_output_cut.rb +17 -0
  177. data/lib/samagotchi/tool_response.rb +5 -3
  178. data/lib/samagotchi/tool_runner.rb +25 -5
  179. data/lib/samagotchi/toolkit_command.rb +1 -1
  180. data/lib/samagotchi/tools/delegate.rb +55 -45
  181. data/lib/samagotchi/tools/delegate_relay.rb +5 -5
  182. data/lib/samagotchi/tools/delegate_result.rb +5 -5
  183. data/lib/samagotchi/tools/delegate_wait.rb +41 -17
  184. data/lib/samagotchi/tools/index_hint.rb +14 -0
  185. data/lib/samagotchi/tools/list_sessions.rb +7 -7
  186. data/lib/samagotchi/tools/registry.rb +28 -11
  187. data/lib/samagotchi/tools/send_note.rb +4 -6
  188. data/lib/samagotchi/tools/tool_index.rb +52 -51
  189. data/lib/samagotchi/tools/tool_surface.rb +22 -8
  190. data/lib/samagotchi/turn_context.rb +2 -1
  191. data/lib/samagotchi/turn_stages/context_judge.rb +38 -36
  192. data/lib/samagotchi/turn_stages/objectives.rb +56 -52
  193. data/lib/samagotchi/turn_stages/toolkit_suggestion.rb +13 -17
  194. data/lib/samagotchi/turn_stages/verify_anchors.rb +9 -10
  195. data/lib/samagotchi/turn_stages/warmup.rb +14 -15
  196. data/lib/samagotchi/update_command.rb +11 -7
  197. data/lib/samagotchi/verify_fresh.rb +7 -11
  198. data/lib/samagotchi/version.rb +1 -1
  199. data/lib/samagotchi/vision_support.rb +11 -14
  200. data/lib/samagotchi/web/app.rb +45 -28
  201. data/lib/samagotchi/web/message_display.rb +57 -7
  202. data/lib/samagotchi/web/participant_access.rb +3 -3
  203. data/lib/samagotchi/web/public/activity.js +16 -7
  204. data/lib/samagotchi/web/public/app.js +29 -8
  205. data/lib/samagotchi/web/public/bubbles.js +8 -3
  206. data/lib/samagotchi/web/public/cards_place.js +15 -0
  207. data/lib/samagotchi/web/public/commands.js +5 -1
  208. data/lib/samagotchi/web/public/data.js +4 -2
  209. data/lib/samagotchi/web/public/history_shape.js +220 -0
  210. data/lib/samagotchi/web/public/recap_stamp.js +17 -0
  211. data/lib/samagotchi/web/public/reload_check.js +71 -0
  212. data/lib/samagotchi/web/public/stage_model.js +7 -5
  213. data/lib/samagotchi/web/public/stage_view.js +7 -3
  214. data/lib/samagotchi/web/public/stream_handlers.js +8 -2
  215. data/lib/samagotchi/web/public/timing.js +43 -2
  216. data/lib/samagotchi/web/public/turn_block.js +215 -30
  217. data/lib/samagotchi/web/public/turn_drawing.js +43 -0
  218. data/lib/samagotchi/web/public/turn_events.js +10 -1
  219. data/lib/samagotchi/web/public/turn_pieces.js +29 -0
  220. data/lib/samagotchi/web/reload_check_route.rb +95 -0
  221. data/lib/samagotchi/web/server.rb +4 -2
  222. data/lib/samagotchi/web/session_access_routes.rb +6 -6
  223. data/lib/samagotchi/web/session_control.rb +4 -4
  224. data/lib/samagotchi/web/session_create.rb +3 -3
  225. data/lib/samagotchi/web/session_hub.rb +9 -17
  226. data/lib/samagotchi/web/session_show.rb +67 -5
  227. data/lib/samagotchi/web/session_summary.rb +39 -28
  228. data/lib/samagotchi/worker.rb +83 -32
  229. data/lib/samagotchi/worker_boot.rb +184 -0
  230. data/lib/samagotchi/worker_link.rb +3 -0
  231. data/lib/samagotchi/worker_signals.rb +1 -1
  232. data/lib/samagotchi/worker_task_wakes.rb +2 -2
  233. metadata +32 -4
  234. data/lib/samagotchi/send_command/wait_target.rb +0 -85
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Samagotchi
4
+ class SessionManager
5
+ # CROSS-VERSION CONTRACT: this boot string, the entry it names
6
+ # (run_session_loop(id, state_dir:), the forwarder below), the env keys
7
+ # spawn_options sets and the input/ file
8
+ # format are read by a NEWER chi than the one writing them. Change them
9
+ # only additively (spec/worker_contract_spec.rb).
10
+ BOOT_FALLBACK_ENV = "SAMAGOTCHI_BOOT_FALLBACK"
11
+ # "1" in a worker spawn_options started: it traps signals (WorkerSignals).
12
+ # WorkerBoot.run_session_loop deletes it from ENV as it reads it.
13
+ WORKER_PROCESS_ENV = "SAMAGOTCHI_WORKER_PROCESS"
14
+ # "1" in a worker spawn_options started: WorkerBoot.run_session_loop
15
+ # leaves the spawner's process tree first (detach_from_spawner); deleted
16
+ # from ENV as it is read, so an rspec run by the worker's execute never
17
+ # forks.
18
+ WORKER_DETACH_ENV = "SAMAGOTCHI_WORKER_DETACH"
19
+
20
+ # The boot string's rescue under a chi home: one line in the spawner's
21
+ # log file (SAMAGOTCHI_LOG_FILE, set by spawn_options), LogLine's shape,
22
+ # then exit. Single-quoted: the #{} run in the worker. SID is replaced.
23
+ # rubocop:disable-next Lint/InterpolationCheck -- the worker interpolates these, not this process
24
+ HOME_BOOT_FAILED = 'rescue ScriptError, StandardError => e; f = ENV["SAMAGOTCHI_LOG_FILE"].to_s; begin; ' \
25
+ 'File.open(f, "a") { |io| io.puts(Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S.%LZ") + ' \
26
+ '" ERROR worker pid=#{Process.pid} sid=SID boot_failed ruby=#{RbConfig.ruby.inspect} error=" + ' \
27
+ "e.message.lines.first.to_s.strip.inspect) } unless f.empty?; rescue SystemCallError; end; exit 1"
28
+
29
+ # WorkerCommand: the worker's command line and env (CROSS-VERSION
30
+ # CONTRACT: spec/worker_contract_spec.rb); the worker process itself is
31
+ # WorkerBoot (worker_boot.rb), which only the forwarder (run_session_loop)
32
+ # loads, as a worker boots. Calls no other part. Meant to be loaded
33
+ # through samagotchi/session_manager.
34
+ module WorkerCommandPart
35
+ # Build the opts hash passed to Process.spawn for a forked worker. The
36
+ # child inherits this process's ENV and reads config.yml itself (as it
37
+ # is when the worker starts); opts[:env] adds to it (merged, not
38
+ # replaced) what it can't read there: this `chi`'s CLI settings
39
+ # (Config.cli_env) and the absolute log file. It unsets
40
+ # what ChildEnv lists (SAMAGOTCHI_GUARDRAILS_*, the session markers).
41
+ # XDG_CONFIG_HOME passes: whoever starts or
42
+ # wakes the worker picks which config.yml it reads (docs/guardrails.md).
43
+ # XDG_STATE_HOME and XDG_CONFIG_HOME, when set, pass made absolute
44
+ # (Paths): the worker starts in the session's directory.
45
+ private def spawn_options(session)
46
+ # Own process group: workers outlive `chi web`, and a Ctrl-C in its
47
+ # terminal must not reach them (the worker then leaves the process
48
+ # tree too: WORKER_DETACH_ENV).
49
+ opts = { out: File::NULL, err: File::NULL, pgroup: true }
50
+ # The worker's tools (and `!cmd`) run in the session's directory, not
51
+ # in the cwd of whoever woke it (`chi web`, another terminal).
52
+ dir = session.working_directory.to_s
53
+ if !dir.empty? && File.directory?(dir)
54
+ opts[:chdir] = dir
55
+ else
56
+ Log.warn(:worker, "cwd_gone", sid: session.id, dir: dir, cwd: Dir.pwd)
57
+ end
58
+ # (A chi a session's tool runs took that session's project env out at
59
+ # its start: bin/chi, ProjectEnv.take_orig!.)
60
+ child_env = {}
61
+ # A worker gets no CLI args: --model, --thinking, --log-level and the
62
+ # other flags this chi was started with.
63
+ child_env.merge!(Config.cli_env)
64
+ child_env[ModelProfile::MODEL_FROM_CLI_ENV] = "1" if child_env.key?(ModelProfile::MODEL_ENV)
65
+ # And the spawner's debug log, absolute: a relative log.file would
66
+ # otherwise land in the worker's (the session's) directory.
67
+ log_path = begin LogPath.resolve rescue nil end # degrade-ok: no log to say it in; the worker's is off (below)
68
+ if log_path
69
+ child_env["SAMAGOTCHI_LOG_FILE"] = log_path
70
+ else
71
+ child_env["SAMAGOTCHI_LOG_DISABLE"] = "true"
72
+ end
73
+ # And the spawner's XDG dirs, absolute: a relative XDG_STATE_HOME or
74
+ # XDG_CONFIG_HOME would otherwise be read from the session's directory.
75
+ child_env.merge!(Paths.absolute_xdg)
76
+ # Unset (Process.spawn unsets a key mapped to nil) what no child chi
77
+ # takes from its spawner (ChildEnv): the spawner's guardrails settings
78
+ # (a parent agent starting or waking a session; config.yml no longer
79
+ # reads them, this keeps an older or future env-exposed one out as
80
+ # well); the session markers, a session's own (a worker started from
81
+ # its commands, chi send, is another session: its execute and tasks
82
+ # set its own; nothing else it runs has one); and a smoke's fake
83
+ # "newest installed", for this process's notices only.
84
+ child_env.merge!(ChildEnv.unset)
85
+ # A worker process: WorkerBoot.run_session_loop traps signals, and
86
+ # leaves this process's tree.
87
+ child_env[WORKER_PROCESS_ENV] = "1"
88
+ child_env[WORKER_DETACH_ENV] = "1"
89
+ # A gem-mode worker activates the newest installed chi itself: under
90
+ # `bundle exec` (a Gemfile that has samagotchi) Bundler's RUBYOPT would
91
+ # hold it to the bundle's version, and its badge would never clear.
92
+ child_env.merge!(ChildEnv.unbundled)
93
+ opts[:env] = child_env unless child_env.empty?
94
+ opts
95
+ end
96
+
97
+ # The worker's entry, the one every boot string names (CROSS-VERSION
98
+ # CONTRACT: spec/worker_contract_spec.rb): it only forwards to
99
+ # WorkerBoot.run_session_loop, which runs the worker process. Looked up
100
+ # by name on purpose: a constant reference here would put SessionManager
101
+ # back into one cycle with Worker, Engine and Bridge (the class map).
102
+ # REMOVE one release after the boot string switches (see
103
+ # ~/.claude/plans/arch-worker-boot.md).
104
+ def run_session_loop(session_id, state_dir: nil, **)
105
+ require_relative "../worker_boot"
106
+ Samagotchi.const_get(:WorkerBoot).run_session_loop(session_id, state_dir: state_dir, **)
107
+ end
108
+
109
+ # The worker's command line. Run from an installed gem, the worker
110
+ # activates the newest installed samagotchi (`>= 0.a`, prereleases
111
+ # count), whoever spawns it: an old chi web, chi send or --attach then
112
+ # starts new workers on the newest chi rather than on its own. Activating
113
+ # the gem also makes its dependencies resolve as its gemspec pins them
114
+ # (reline ~> 0.6.3). Should that fail (a broken newest install), the
115
+ # worker falls back to the spawner's own version and logs why.
116
+ #
117
+ # A source checkout (bin/chi, bundle exec; InstalledGem.spec is nil
118
+ # there) keeps the plain -I lib: a worktree's bin/chi spawns its own code.
119
+ def worker_command(session_id, state_dir:, gem_spec: InstalledGem.spec,
120
+ home: ChiHome.current(gem_spec: gem_spec))
121
+ boot = "require 'samagotchi/session_manager'; " \
122
+ "Samagotchi::SessionManager.run_session_loop('#{session_id}', state_dir: #{state_dir.inspect})"
123
+ return [RbConfig.ruby, "-I", File.expand_path("../..", __dir__), "-e", boot] unless gem_spec
124
+ return home_worker_command(session_id, state_dir: state_dir, gem_spec: gem_spec, home: home) if home
125
+
126
+ activate = "begin; gem 'samagotchi', '>= 0.a'; rescue LoadError => e; " \
127
+ "ENV['#{BOOT_FALLBACK_ENV}'] = e.message; gem 'samagotchi', '= #{gem_spec.version}'; end"
128
+ [RbConfig.ruby, "-e", "#{activate}; #{boot}"]
129
+ end
130
+
131
+ # With a chi home (ChiHome.current, docs/architecture.md "How chi
132
+ # launches itself"): the home's ruby, `Gem.paths` set to its gems in the
133
+ # boot string (no GEM_* in the worker's env), the newest chi there, else
134
+ # the fallback pin (ChiHome.fallback_version). A home that still can't
135
+ # load chi (a broken install) logs HOME_BOOT_FAILED and exits: never a
136
+ # silent spawn timeout.
137
+ private def home_worker_command(session_id, state_dir:, gem_spec:, home:)
138
+ newest = home.newest_version
139
+ if newest && newest < Gem::Version.new(gem_spec.version.to_s)
140
+ ChiHome.warn_once(:older_than_spawner, home: newest.to_s, spawner: gem_spec.version.to_s)
141
+ end
142
+ fallback = ChiHome.fallback_version(home, gem_spec)
143
+ activate = if fallback
144
+ "begin; gem 'samagotchi', '>= 0.a'; rescue LoadError => e; " \
145
+ "ENV['#{BOOT_FALLBACK_ENV}'] = e.message; gem 'samagotchi', '= #{fallback}'; end"
146
+ else
147
+ "gem 'samagotchi', '>= 0.a'"
148
+ end
149
+ home.boot_argv(run: "begin; #{activate}; require 'samagotchi/session_manager'; " \
150
+ "#{HOME_BOOT_FAILED.sub("SID", session_id)}; end; " \
151
+ "Samagotchi::SessionManager.run_session_loop('#{session_id}', state_dir: #{state_dir.inspect})")
152
+ end
153
+ end
154
+
155
+ extend WorkerCommandPart
156
+ end
157
+ end