samagotchi 0.150.0 → 0.151.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -1
  3. data/docs/architecture.md +2 -2
  4. data/docs/bundle-authoring.md +1 -1
  5. data/docs/configuration.md +1 -1
  6. data/docs/internals/block-renderers.md +96 -0
  7. data/docs/internals/bridge.md +53 -17
  8. data/docs/internals/bundles.md +1 -0
  9. data/docs/internals/web-frontend.md +2 -2
  10. data/docs/memory.md +1 -1
  11. data/docs/plugins.md +43 -3
  12. data/lib/samagotchi/block_renderers.rb +115 -0
  13. data/lib/samagotchi/bridge/card_places.rb +93 -0
  14. data/lib/samagotchi/bridge/card_store.rb +219 -122
  15. data/lib/samagotchi/bridge.rb +12 -4
  16. data/lib/samagotchi/bundle_command/try/trace.rb +1 -1
  17. data/lib/samagotchi/bundles/system/manifest.yml +1 -1
  18. data/lib/samagotchi/engine.rb +20 -2
  19. data/lib/samagotchi/memory_bundle/asset_installer.rb +7 -1
  20. data/lib/samagotchi/memory_bundle/builder.rb +5 -3
  21. data/lib/samagotchi/memory_bundle/installed_bundle.rb +8 -5
  22. data/lib/samagotchi/memory_bundle/installed_copy.rb +1 -0
  23. data/lib/samagotchi/memory_bundle/installer.rb +1 -0
  24. data/lib/samagotchi/memory_bundle/manifest.rb +23 -2
  25. data/lib/samagotchi/memory_bundle/provenance.rb +4 -2
  26. data/lib/samagotchi/session_chain.rb +2 -7
  27. data/lib/samagotchi/session_commands.rb +15 -9
  28. data/lib/samagotchi/session_manager.rb +10 -7
  29. data/lib/samagotchi/steer.rb +17 -0
  30. data/lib/samagotchi/terminal_ui.rb +4 -4
  31. data/lib/samagotchi/turn_checkpoint.rb +11 -5
  32. data/lib/samagotchi/turn_flow.rb +2 -3
  33. data/lib/samagotchi/version.rb +1 -1
  34. data/lib/samagotchi/web/app.rb +22 -12
  35. data/lib/samagotchi/web/block_renderer_routes.rb +32 -0
  36. data/lib/samagotchi/web/markdown_renderer.rb +39 -6
  37. data/lib/samagotchi/web/message_display.rb +3 -3
  38. data/lib/samagotchi/web/participant_view.rb +1 -1
  39. data/lib/samagotchi/web/public/app.js +2 -0
  40. data/lib/samagotchi/web/public/block_frame.js +202 -0
  41. data/lib/samagotchi/web/public/block_host.js +502 -0
  42. data/lib/samagotchi/web/public/block_renderers.css +20 -0
  43. data/lib/samagotchi/web/public/block_source.js +37 -0
  44. data/lib/samagotchi/web/public/bubbles.js +9 -5
  45. data/lib/samagotchi/web/public/card.js +17 -10
  46. data/lib/samagotchi/web/public/cards_place.js +2 -2
  47. data/lib/samagotchi/web/public/claim_link.js +4 -2
  48. data/lib/samagotchi/web/public/history_reveal.js +4 -1
  49. data/lib/samagotchi/web/public/index.html +2 -0
  50. data/lib/samagotchi/web/public/markdown_place.js +2 -3
  51. data/lib/samagotchi/web/public/text_roots.js +6 -0
  52. data/lib/samagotchi/web/public/turn_html.js +4 -1
  53. data/lib/samagotchi/web/session_show.rb +1 -1
  54. data/lib/samagotchi/worker.rb +4 -2
  55. metadata +10 -1
@@ -325,12 +325,14 @@ export function showClaim(container, claim, { roots: rootSelector, opts = {}, do
325
325
  const hit = findClaim(texts.map((t) => t.text), claim, opts);
326
326
  if (!hit && !turn) return null;
327
327
  const el = hit ? roots[hit.at] : turn.anchor;
328
+ const start = hit && pointAt(texts[hit.at], hit.start);
329
+ const end = hit && pointAt(texts[hit.at], hit.end, true);
328
330
  revealInHistory(el);
331
+ // The text can be somewhere its root isn't: a drawn block's hidden source.
332
+ if (start) revealInHistory(start.node.parentElement);
329
333
  el.classList.add(HIT_CLASS);
330
334
  el.scrollIntoView?.({ block: "center" });
331
335
  if (hit) {
332
- const start = pointAt(texts[hit.at], hit.start);
333
- const end = pointAt(texts[hit.at], hit.end, true);
334
336
  const highlights = win?.CSS?.highlights;
335
337
  if (start && end && highlights && typeof win.Highlight === "function") {
336
338
  const range = doc.createRange();
@@ -2,7 +2,8 @@
2
2
  // hides +el+ unfolds: a closed <details> around it (a turn's steps block, a
3
3
  // step, a diff), an answer or a delegate report folded (answer_fold.js: its row follows
4
4
  // the bubble's class; the jump's unfold isn't saved), a superseded version
5
- // of a Revise stack (revise_stack.js: its stub opens, not saved). Every
5
+ // of a Revise stack (revise_stack.js: its stub opens, not saved), a drawn
6
+ // block's source (block_source.js). Every
6
7
  // jump goes through it (claim_link.js showClaim, refs.js showRow and so the
7
8
  // working set's step tags, verdict_card.js "View check"), so a new way to
8
9
  // hide history is opened in one place.
@@ -11,6 +12,7 @@
11
12
  // own: static JS is cached at unversioned URLs, and a new export on an old
12
13
  // module would blank the page.
13
14
 
15
+ import { revealBlockSource } from "./block_source.js";
14
16
  import { openStubOver } from "./revise_stack.js";
15
17
 
16
18
  // Opens each closed <details> that holds +el+ (not +el+ itself: a fold the
@@ -19,6 +21,7 @@ import { openStubOver } from "./revise_stack.js";
19
21
  export function revealInHistory(el) {
20
22
  if (!el) return null;
21
23
  openStubOver(el);
24
+ revealBlockSource(el);
22
25
  el.closest?.(".bubble.folded")?.classList.remove("folded");
23
26
  for (let details = el.parentElement?.closest("details"); details; details = details.parentElement?.closest("details")) {
24
27
  details.open = true;
@@ -15,6 +15,7 @@
15
15
  <link rel="stylesheet" href="/assets/composer.css">
16
16
  <link rel="stylesheet" href="/assets/forms.css">
17
17
  <link rel="stylesheet" href="/assets/objectives.css">
18
+ <link rel="stylesheet" href="/assets/block_renderers.css">
18
19
  <style>
19
20
  /* Icon masks shared by the phone info bar and the all view's cards (the stroke only shapes the mask; the icon takes currentColor); the image icon is composer.css's. */
20
21
  :root{--icon-archive:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2' y='2.75' width='12' height='3.5' rx='1'/%3E%3Cpath d='M3.25 6.25v6a1 1 0 0 0 1 1h7.5a1 1 0 0 0 1-1v-6M6.5 9h3'/%3E%3C/svg%3E");--icon-unarchive:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2' y='2.75' width='12' height='3.5' rx='1'/%3E%3Cpath d='M3.25 6.25v6a1 1 0 0 0 1 1h7.5a1 1 0 0 0 1-1v-6M8 11.5V8.25M6.5 9.75 8 8.25l1.5 1.5'/%3E%3C/svg%3E")}
@@ -609,6 +610,7 @@ button.system-one-wrong,.system-one-wrong.marked{flex:none;padding:1px 6px;borde
609
610
  .card-head{display:flex;align-items:baseline;gap:8px;margin-bottom:4px}
610
611
  .card-title{font-size:14px;font-weight:600;color:var(--text-bright)}
611
612
  .card-source{font-size:11px;color:var(--text-faint);font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
613
+ .card-label{font-size:11px;color:var(--text-faint)}
612
614
  .card-body{font-size:13.5px;color:var(--text-2);white-space:normal;line-height:1.5}
613
615
  .card-body p{margin:0 0 6px}.card-body p:last-child{margin-bottom:0}
614
616
  .card-body ul,.card-body ol{margin:0 0 6px 20px}
@@ -4,9 +4,8 @@
4
4
  // page's state comes in as getters (capabilities, roots, currentDir), read
5
5
  // at each call.
6
6
 
7
- // The texts whose refs linkTextRefs links: the answers and the closed
8
- // steps' texts.
9
- const TEXTS = ".bubble.output, .gen:not(.live) > .gen-text";
7
+ import { TEXTS } from "./text_roots.js";
8
+
10
9
  // The closed steps' texts still shown raw: a live turn's (a reload's come
11
10
  // rendered, turn_block.js textTemplate).
12
11
  const RAW_STEPS = ".gen:not(.live) > .gen-text:not(.markdown)";
@@ -0,0 +1,6 @@
1
+ // The texts the page treats as text it wrote out of a model's words: the
2
+ // answers and the closed steps' texts. Cards, question replies, the asking
3
+ // slot and delegate reports aren't among them. markdown_place.js links refs on
4
+ // these; block_host.js draws in these. A module of its own: static JS is cached
5
+ // at unversioned URLs, and a new export on an old module would blank the page.
6
+ export const TEXTS = ".bubble.output, .gen:not(.live) > .gen-text";
@@ -284,7 +284,10 @@ export function answerBubbleTemplate(message, { cls = "", at = null, turnId = nu
284
284
  export function noteBubbleTemplate(note) {
285
285
  if (note?.objectives) return objectivesEntryTemplate(note, timeTitle(note.at));
286
286
  const from = note?.label ? `note from ${note.label}` : "note";
287
- return html`<div class="bubble note" title=${timeTitle(note?.at)}><div class="note-line">${from}</div><div class="note-text">${note?.content ?? ""}</div></div>`;
287
+ // A wake turn's note opens that turn (TURN_PROMPT, bubbles.js); a class, not
288
+ // data-turn-id, which marks a claim's anchor (claim_link.js).
289
+ const cls = note?.turn_start ? "bubble note turn-start" : "bubble note";
290
+ return html`<div class=${cls} title=${timeTitle(note?.at)}><div class="note-line">${from}</div><div class="note-text">${note?.content ?? ""}</div></div>`;
288
291
  }
289
292
 
290
293
  // A plugin's steer (a nudge put into the running turn): one line that
@@ -80,7 +80,7 @@ module Samagotchi
80
80
  plugin_warning: turn_snapshot && turn_snapshot["plugin_warning"],
81
81
  # Plugins' slow setup still running (chi.init): the page's init row.
82
82
  init_tasks: snapshot_list(turn_snapshot, "init_tasks"),
83
- cards: cards_for_display(live_or_saved(turn_snapshot, "cards") { saved_cards(id) }, cwd: session.working_directory),
83
+ cards: cards_for_display(live_or_saved(turn_snapshot, "cards") { saved_cards(id, messages: raw_messages) }, cwd: session.working_directory),
84
84
  # The composer's / autocomplete; the built-ins until a worker
85
85
  # names its plugins' too.
86
86
  commands: turn_snapshot&.fetch("commands", nil) || SessionCommands.builtin_registry.listing,
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "fileutils"
4
+ require "securerandom"
4
5
 
5
6
  require_relative "client_id"
6
7
  require_relative "config"
@@ -1263,14 +1264,15 @@ module Samagotchi
1263
1264
  # a fresh worker's first), so the list is this turn's from the start.
1264
1265
  @merged_this_turn = []
1265
1266
  origin = fresh_origin(turn_args[:origin])
1266
- turn_args = turn_args.merge(origin: origin)
1267
+ # Settled here: the checkpoint's prompt carries it from the start.
1268
+ turn_args = turn_args.merge(origin: origin, id: turn_args[:id] || SecureRandom.uuid)
1267
1269
  verdicts_before = @session.verdicts.size
1268
1270
  @reporting_turn = reports_to_parent?(origin)
1269
1271
  # A participant's review turn merges no input (#pending_input_drain).
1270
1272
  @participant_turn = origin.participant?
1271
1273
  restores = @turn_flow.restores
1272
1274
  begin
1273
- @checkpoint.begin_turn(prompt: prompt, enqueued_id: origin.enqueued_id, author: turn_author_fields(origin))
1275
+ @checkpoint.begin_turn(prompt: prompt, turn_id: turn_args[:id], enqueued_id: origin.enqueued_id, author: turn_author_fields(origin))
1274
1276
  @session.status = Session::STATUS_RUNNING
1275
1277
  # A continue that moved this session to the chain's new link wrote
1276
1278
  # the new parent beside it (Session::PARENT_FILE): this turn's
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.150.0
4
+ version: 0.151.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Dedov
@@ -155,6 +155,7 @@ files:
155
155
  - docs/internals/anthropic.md
156
156
  - docs/internals/attached-context.md
157
157
  - docs/internals/background-tasks.md
158
+ - docs/internals/block-renderers.md
158
159
  - docs/internals/bridge.md
159
160
  - docs/internals/bundles.md
160
161
  - docs/internals/context-telemetry.md
@@ -186,12 +187,14 @@ files:
186
187
  - lib/samagotchi/answer_tail.rb
187
188
  - lib/samagotchi/archive_store.rb
188
189
  - lib/samagotchi/atomic_file.rb
190
+ - lib/samagotchi/block_renderers.rb
189
191
  - lib/samagotchi/bootstrap/bundles.rb
190
192
  - lib/samagotchi/bootstrap/config_writer.rb
191
193
  - lib/samagotchi/bootstrap/probe.rb
192
194
  - lib/samagotchi/bootstrap_command.rb
193
195
  - lib/samagotchi/bridge.rb
194
196
  - lib/samagotchi/bridge/bounded_queue.rb
197
+ - lib/samagotchi/bridge/card_places.rb
195
198
  - lib/samagotchi/bridge/card_store.rb
196
199
  - lib/samagotchi/bridge/client_event.rb
197
200
  - lib/samagotchi/bridge/event_id.rb
@@ -799,6 +802,7 @@ files:
799
802
  - lib/samagotchi/web/app.rb
800
803
  - lib/samagotchi/web/auto_update.rb
801
804
  - lib/samagotchi/web/auto_update_record.rb
805
+ - lib/samagotchi/web/block_renderer_routes.rb
802
806
  - lib/samagotchi/web/capabilities.rb
803
807
  - lib/samagotchi/web/editor.rb
804
808
  - lib/samagotchi/web/grants.rb
@@ -828,7 +832,11 @@ files:
828
832
  - lib/samagotchi/web/public/app.js
829
833
  - lib/samagotchi/web/public/apple-touch-icon.png
830
834
  - lib/samagotchi/web/public/auth_lost.js
835
+ - lib/samagotchi/web/public/block_frame.js
836
+ - lib/samagotchi/web/public/block_host.js
831
837
  - lib/samagotchi/web/public/block_open.js
838
+ - lib/samagotchi/web/public/block_renderers.css
839
+ - lib/samagotchi/web/public/block_source.js
832
840
  - lib/samagotchi/web/public/bubbles.js
833
841
  - lib/samagotchi/web/public/card.js
834
842
  - lib/samagotchi/web/public/cards_place.js
@@ -953,6 +961,7 @@ files:
953
961
  - lib/samagotchi/web/public/system_one_wrong.js
954
962
  - lib/samagotchi/web/public/tally.js
955
963
  - lib/samagotchi/web/public/task_stop.js
964
+ - lib/samagotchi/web/public/text_roots.js
956
965
  - lib/samagotchi/web/public/thinking_chip.js
957
966
  - lib/samagotchi/web/public/thinking_ticker.js
958
967
  - lib/samagotchi/web/public/time_gaps.js