samagotchi 0.56.0 → 0.58.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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +54 -1
  3. data/README.md +1 -1
  4. data/docs/cli.md +1 -1
  5. data/docs/configuration.md +5 -3
  6. data/docs/hooks.md +2 -2
  7. data/docs/memory.md +1 -1
  8. data/docs/plugins.md +63 -0
  9. data/docs/sessions.md +2 -2
  10. data/lib/samagotchi/bootstrap/config_writer.rb +2 -0
  11. data/lib/samagotchi/bootstrap/probe.rb +3 -0
  12. data/lib/samagotchi/bootstrap_command.rb +2 -0
  13. data/lib/samagotchi/broadcast_command.rb +2 -0
  14. data/lib/samagotchi/bundles/core/manifest.yml +2 -1
  15. data/lib/samagotchi/bundles/mcp/manifest.yml +2 -2
  16. data/lib/samagotchi/bundles/mcp/plugin.rb +15 -1
  17. data/lib/samagotchi/bundles/slow-commands/manifest.yml +11 -0
  18. data/lib/samagotchi/bundles/slow-commands/plugin.rb +320 -0
  19. data/lib/samagotchi/bundles/system/manifest.yml +2 -2
  20. data/lib/samagotchi/bundles/system/memory_guide.md +1 -1
  21. data/lib/samagotchi/context_command.rb +2 -0
  22. data/lib/samagotchi/desktop/macos.rb +3 -0
  23. data/lib/samagotchi/engine.rb +2 -2
  24. data/lib/samagotchi/gem_update.rb +3 -0
  25. data/lib/samagotchi/guardrails/shell_lex.rb +8 -0
  26. data/lib/samagotchi/guardrails/shell_paths.rb +3 -0
  27. data/lib/samagotchi/host_registry.rb +15 -0
  28. data/lib/samagotchi/installed_versions.rb +3 -0
  29. data/lib/samagotchi/model_profile.rb +14 -3
  30. data/lib/samagotchi/plugin/context.rb +5 -0
  31. data/lib/samagotchi/redacted_inspect.rb +43 -0
  32. data/lib/samagotchi/session_commands.rb +5 -4
  33. data/lib/samagotchi/terminal_ui/attached_loop.rb +13 -8
  34. data/lib/samagotchi/terminal_ui.rb +14 -5
  35. data/lib/samagotchi/tool_runner.rb +14 -3
  36. data/lib/samagotchi/tools/execute.rb +3 -2
  37. data/lib/samagotchi/version.rb +1 -1
  38. data/lib/samagotchi/web/app.rb +14 -6
  39. data/lib/samagotchi/web/public/app.js +31 -14
  40. data/lib/samagotchi/web/public/index.html +32 -5
  41. data/lib/samagotchi/web/public/question_card.js +5 -3
  42. data/lib/samagotchi/web/public/question_cards.js +21 -1
  43. data/lib/samagotchi/web/public/read_view.js +74 -0
  44. data/lib/samagotchi/web/public/ref_menu.js +188 -0
  45. data/lib/samagotchi/web/public/ref_scan.js +216 -0
  46. data/lib/samagotchi/web/public/refs.js +283 -54
  47. data/lib/samagotchi/web/public/stage_view.js +21 -0
  48. data/lib/samagotchi/web/public/turn_html.js +4 -2
  49. data/lib/samagotchi/web/public/turn_view.js +5 -3
  50. data/lib/samagotchi/web/token.rb +3 -0
  51. data/lib/samagotchi/worker.rb +2 -2
  52. metadata +7 -1
@@ -106,6 +106,8 @@ export function createStageView({ historyEl, appendToHistory, isNearBottom: hist
106
106
  let flash = null; // { kind, text, until } a notice or nudge in the trail
107
107
  let collapsed = readCollapsed();
108
108
  let cloudOpen = false;
109
+ // A ref's "show in turn" opened a collapsed stage (not kept).
110
+ let revealed = false;
109
111
  let rafPending = false;
110
112
  let foldTimer = null;
111
113
  let watchTimer = null;
@@ -326,6 +328,7 @@ export function createStageView({ historyEl, appendToHistory, isNearBottom: hist
326
328
 
327
329
  function setCollapsed(value) {
328
330
  collapsed = value;
331
+ revealed = false;
329
332
  try { localStorage.setItem(COLLAPSE_KEY, value ? "1" : "0"); } catch (_) {}
330
333
  applyCollapsed();
331
334
  }
@@ -370,6 +373,19 @@ export function createStageView({ historyEl, appendToHistory, isNearBottom: hist
370
373
  else setCloud(!cloudOpen);
371
374
  });
372
375
  headline.addEventListener("click", peek);
376
+ // A ref's "show in turn" (refs.js) names a row in the cloud: open the
377
+ // stage and the cloud to it, as a hand toggle would.
378
+ // A collapsed stage opens for this turn only: the kept choice
379
+ // (chi_stage_collapsed) is left alone and comes back at the release.
380
+ stage.addEventListener("ref:reveal", (e) => {
381
+ if (!cloudBody.contains(e.target)) return;
382
+ if (collapsed) {
383
+ collapsed = false;
384
+ revealed = true;
385
+ applyCollapsed();
386
+ }
387
+ setCloud(true);
388
+ });
373
389
  headline.addEventListener("keydown", (e) => {
374
390
  if (e.key === "Enter" || e.key === " ") {
375
391
  e.preventDefault();
@@ -491,6 +507,11 @@ export function createStageView({ historyEl, appendToHistory, isNearBottom: hist
491
507
  settled = true;
492
508
  view.reset();
493
509
  emptySlots();
510
+ if (revealed) {
511
+ revealed = false;
512
+ collapsed = readCollapsed();
513
+ applyCollapsed();
514
+ }
494
515
  }
495
516
 
496
517
  // Everything the stage holds, into the history's end in the turn view's
@@ -8,6 +8,7 @@ import { copySourceAttr } from "./copy.js";
8
8
  import { activityDiffHtml } from "./diff_view.js";
9
9
  import { escapeHtml, userBodyHtml } from "./format.js";
10
10
  import { refAttrs } from "./refs.js";
11
+ import { readLinesHtml } from "./read_view.js";
11
12
  import { formatDuration } from "./timing.js";
12
13
  import { emptyAnswerLine } from "./turn_events.js";
13
14
 
@@ -72,7 +73,8 @@ function llmEditHtml(row) {
72
73
  // else the full params line, on hover), the word an exception shows, the
73
74
  // call's duration, the full command (an execute/task_create's view, also
74
75
  // while it runs), the output once done (its "[tool]" tag dropped, 300 chars,
75
- // the rest on hover), its images (+thumbs+(images) draws them) and an
76
+ // the rest on hover; a read of the file as-is also its numbered lines,
77
+ // closed: read_view.js), its images (+thumbs+(images) draws them) and an
76
78
  // edit's collapsed diff, and a reloaded row's ✂ mark above its output. A
77
79
  // part with nothing to say is left out.
78
80
  export function toolRowHtml(row, { thumbs = () => "" } = {}) {
@@ -96,7 +98,7 @@ export function toolRowInnerHtml(row, { thumbs = () => "" } = {}) {
96
98
  const status = statusParts(row.status, { noMatch: !!row.no_match });
97
99
  return `${statusMarkHtml(status)}<span class="activity-tool">${escapeHtml(toolName(row))}</span>${params}${alias}${statusWordHtml(status)}` +
98
100
  `${duration ? `<span class="activity-duration">${escapeHtml(duration)}</span>` : ""}` +
99
- `${commandBlockHtml(row.view, row.title)}${llmEditHtml(row)}${output}` +
101
+ `${commandBlockHtml(row.view, row.title)}${llmEditHtml(row)}${output}${output ? readLinesHtml(row) : ""}` +
100
102
  `${row.images?.length ? thumbs(row.images) : ""}${row.diff ? activityDiffHtml(row.diff) : ""}`;
101
103
  }
102
104
 
@@ -63,13 +63,15 @@ export function thinkingTemplate({ body, wrapped = true, line = null, cls = "thi
63
63
 
64
64
  // A step's narration: the live box of complete sentences (one per line,
65
65
  // the newest last), the live "…" until the first one, or a closed step's
66
- // full text. None when there is nothing to say.
66
+ // full text. None when there is nothing to say. A closed step's text is
67
+ // set whole (.textContent): its refs (ref_scan.js) split it into spans
68
+ // that a text part's update would leave behind.
67
69
  function textTemplate(text, { live, sentences, placeholder }) {
68
70
  if (live && sentences?.length) {
69
71
  return html`<div class="gen-text streaming"><div class="narration">${sentences.map((s) => html`<div class="sentence">${s}</div>`)}</div></div>`;
70
72
  }
71
73
  if (live) return placeholder ? html`<div class="gen-text streaming">…</div>` : nothing;
72
- return text ? html`<div class="gen-text">${text}</div>` : nothing;
74
+ return text ? html`<div class="gen-text" .textContent=${text}></div>` : nothing;
73
75
  }
74
76
 
75
77
  // One step, live or reloaded. +gen+: { text, thinking, tools, answer } (a
@@ -118,7 +120,7 @@ function rawNodes(markup) {
118
120
  // The parts of a drawn tool row a user may have changed (the command's
119
121
  // raw toggle, an opened diff) or that never change once there (the
120
122
  // thumbs): a redraw keeps them as they are.
121
- const KEPT_PARTS = ["activity-command", "activity-diff", "thumbs"];
123
+ const KEPT_PARTS = ["activity-command", "activity-diff", "activity-read", "thumbs"];
122
124
 
123
125
  const childWith = (el, cls) => [...el.children].find((c) => c.classList.contains(cls));
124
126
 
@@ -5,6 +5,7 @@ require "securerandom"
5
5
  require_relative "../atomic_file"
6
6
 
7
7
  require_relative "../session"
8
+ require_relative "../redacted_inspect"
8
9
 
9
10
  module Samagotchi
10
11
  module Web
@@ -62,6 +63,8 @@ module Samagotchi
62
63
  # its mtime changes (one stat per check), so `chi web --new-token`
63
64
  # takes effect at once, without a restart.
64
65
  class Source
66
+ include RedactedInspect
67
+
65
68
  attr_reader :path
66
69
 
67
70
  def initialize(path = Token.path)
@@ -219,8 +219,8 @@ module Samagotchi
219
219
  @bridge.queue_command(line, client_id: client_id, after_file: after_file)
220
220
  })
221
221
  # /model's default is the config's, as in the REPL; the Engine started
222
- # on the session's model.
223
- @default_model = ModelProfile.required_model_name(nil)
222
+ # on the session's model. nil when there is no default.model.
223
+ @default_model = ModelProfile.default_model_name
224
224
  @commands = SessionCommands.new(engine: @engine, turn_flow: @turn_flow,
225
225
  default_model: @default_model, registry: @engine.command_registry,
226
226
  save: ->(session) { session.save(state_dir: @state_dir) })
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.56.0
4
+ version: 0.58.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Dedov
@@ -203,6 +203,8 @@ files:
203
203
  - lib/samagotchi/bundles/mcp/plugin.rb
204
204
  - lib/samagotchi/bundles/skills/manifest.yml
205
205
  - lib/samagotchi/bundles/skills/plugin.rb
206
+ - lib/samagotchi/bundles/slow-commands/manifest.yml
207
+ - lib/samagotchi/bundles/slow-commands/plugin.rb
206
208
  - lib/samagotchi/bundles/source-links/hooks/source_links.rb
207
209
  - lib/samagotchi/bundles/source-links/manifest.yml
208
210
  - lib/samagotchi/bundles/source-links/source_links.md
@@ -400,6 +402,7 @@ files:
400
402
  - lib/samagotchi/reasoning_history_command.rb
401
403
  - lib/samagotchi/recap_setup.rb
402
404
  - lib/samagotchi/recap_store.rb
405
+ - lib/samagotchi/redacted_inspect.rb
403
406
  - lib/samagotchi/relay.rb
404
407
  - lib/samagotchi/relay_desk.rb
405
408
  - lib/samagotchi/relay_verifier.rb
@@ -557,7 +560,10 @@ files:
557
560
  - lib/samagotchi/web/public/prompt_history.js
558
561
  - lib/samagotchi/web/public/question_card.js
559
562
  - lib/samagotchi/web/public/question_cards.js
563
+ - lib/samagotchi/web/public/read_view.js
560
564
  - lib/samagotchi/web/public/reasoning_history_chip.js
565
+ - lib/samagotchi/web/public/ref_menu.js
566
+ - lib/samagotchi/web/public/ref_scan.js
561
567
  - lib/samagotchi/web/public/refs.js
562
568
  - lib/samagotchi/web/public/restore.js
563
569
  - lib/samagotchi/web/public/route.js