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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +57 -1
- data/bin/chi +2 -1
- data/docs/architecture.md +22 -13
- data/docs/bundles.md +3 -1
- data/docs/cli.md +9 -8
- data/docs/configuration.md +36 -4
- data/docs/guardrails.md +9 -5
- data/docs/hooks.md +11 -5
- data/docs/internals/anthropic.md +1 -1
- data/docs/internals/attached-context.md +3 -2
- data/docs/internals/background-tasks.md +1 -1
- data/docs/internals/bridge.md +83 -6
- data/docs/internals/bundles.md +28 -18
- data/docs/internals/context-telemetry.md +4 -3
- data/docs/internals/engine.md +641 -937
- data/docs/internals/llm-context-forget.md +8 -3
- data/docs/internals/objectives.md +2 -2
- data/docs/internals/participants.md +3 -2
- data/docs/internals/prompt-caching.md +4 -1
- data/docs/internals/remote-sessions.md +8 -3
- data/docs/internals/web-frontend.md +3 -2
- data/docs/internals/working-set.md +2 -2
- data/docs/memory.md +13 -2
- data/docs/plugins.md +35 -2
- data/docs/sessions.md +11 -11
- data/docs/sub-agent.md +17 -2
- data/docs/system-one.md +3 -2
- data/docs/testing.md +53 -2
- data/lib/samagotchi/answer_command.rb +2 -1
- data/lib/samagotchi/archive_store.rb +4 -3
- data/lib/samagotchi/bootstrap/config_writer.rb +1 -1
- data/lib/samagotchi/bootstrap_command.rb +3 -2
- data/lib/samagotchi/bridge/card_places.rb +10 -4
- data/lib/samagotchi/bridge/card_store.rb +3 -0
- data/lib/samagotchi/bridge/turn_accumulator.rb +109 -9
- data/lib/samagotchi/bridge/turn_drawings.rb +265 -0
- data/lib/samagotchi/bridge.rb +31 -6
- data/lib/samagotchi/broadcast/recipients.rb +8 -8
- data/lib/samagotchi/broadcast/triage_model.rb +1 -1
- data/lib/samagotchi/broadcast_command.rb +3 -3
- data/lib/samagotchi/bundle_command/check.rb +18 -0
- data/lib/samagotchi/bundle_command/try/sandbox.rb +2 -2
- data/lib/samagotchi/bundle_command/try/trace.rb +1 -1
- data/lib/samagotchi/bundle_command.rb +5 -2
- data/lib/samagotchi/bundles/known-names/manifest.yml +4 -7
- data/lib/samagotchi/bundles/known-names/{hooks/known_names.rb → plugin.rb} +17 -0
- data/lib/samagotchi/bundles/source-links/manifest.yml +4 -7
- data/lib/samagotchi/bundles/source-links/{hooks/source_links.rb → plugin.rb} +23 -4
- data/lib/samagotchi/bundles/system/config_modification_protocol.md +2 -2
- data/lib/samagotchi/bundles/system/manifest.yml +3 -3
- data/lib/samagotchi/bundles/system/memory_guide.md +1 -1
- data/lib/samagotchi/child_move.rb +13 -57
- data/lib/samagotchi/child_reports.rb +2 -2
- data/lib/samagotchi/children_status.rb +15 -21
- data/lib/samagotchi/cli/parent_wait.rb +9 -23
- data/lib/samagotchi/config.rb +20 -112
- data/lib/samagotchi/context_command.rb +1 -2
- data/lib/samagotchi/context_sources.rb +5 -4
- data/lib/samagotchi/context_window.rb +9 -12
- data/lib/samagotchi/desktop/macos.rb +1 -1
- data/lib/samagotchi/effective_model.rb +57 -22
- data/lib/samagotchi/engine/context_judge.rb +19 -11
- data/lib/samagotchi/engine/messages.rb +1 -1
- data/lib/samagotchi/engine/models.rb +5 -2
- data/lib/samagotchi/engine/objectives.rb +29 -11
- data/lib/samagotchi/engine/plugins.rb +1 -1
- data/lib/samagotchi/engine/recap.rb +8 -4
- data/lib/samagotchi/engine/side_requests.rb +21 -11
- data/lib/samagotchi/engine/toolkit.rb +10 -9
- data/lib/samagotchi/engine/turn_end.rb +1 -1
- data/lib/samagotchi/engine/turn_helpers.rb +7 -7
- data/lib/samagotchi/engine/verify.rb +1 -1
- data/lib/samagotchi/engine.rb +43 -12
- data/lib/samagotchi/events.rb +3 -2
- data/lib/samagotchi/extension_load.rb +6 -3
- data/lib/samagotchi/guardrails/targets.rb +24 -9
- data/lib/samagotchi/guardrails_command.rb +1 -1
- data/lib/samagotchi/host_address.rb +52 -0
- data/lib/samagotchi/host_config.rb +72 -1
- data/lib/samagotchi/host_model.rb +2 -6
- data/lib/samagotchi/host_registry.rb +58 -46
- data/lib/samagotchi/kernel_loop.rb +53 -124
- data/lib/samagotchi/llm/anthropic_wire.rb +2 -2
- data/lib/samagotchi/llm/chat_loop.rb +40 -21
- data/lib/samagotchi/llm/native_backend.rb +1 -1
- data/lib/samagotchi/llm_context_apply.rb +54 -1
- data/lib/samagotchi/llm_context_notice.rb +1 -1
- data/lib/samagotchi/llm_context_strategy.rb +29 -67
- data/lib/samagotchi/llm_context_view.rb +9 -0
- data/lib/samagotchi/memory_bundle/asset_installer.rb +71 -76
- data/lib/samagotchi/memory_bundle/builder.rb +2 -1
- data/lib/samagotchi/memory_bundle/file_actions.rb +193 -0
- data/lib/samagotchi/memory_bundle/file_digest.rb +13 -0
- data/lib/samagotchi/memory_bundle/file_state.rb +152 -0
- data/lib/samagotchi/memory_bundle/installed_copy.rb +2 -1
- data/lib/samagotchi/memory_bundle/installed_manifest.rb +8 -1
- data/lib/samagotchi/memory_bundle/installer.rb +185 -169
- data/lib/samagotchi/memory_bundle/manifest.rb +14 -4
- data/lib/samagotchi/memory_bundle/merger.rb +69 -65
- data/lib/samagotchi/memory_bundle/plugin_ref.rb +6 -5
- data/lib/samagotchi/memory_bundle/profile.rb +5 -5
- data/lib/samagotchi/memory_bundle/provenance.rb +15 -1
- data/lib/samagotchi/memory_bundle/remerge.rb +25 -12
- data/lib/samagotchi/memory_bundle/shipped_update.rb +51 -6
- data/lib/samagotchi/memory_bundle/status.rb +14 -20
- data/lib/samagotchi/memory_bundle/system_bundle.rb +24 -6
- data/lib/samagotchi/memory_bundle/trash.rb +23 -8
- data/lib/samagotchi/memory_bundle/uninstaller.rb +16 -11
- data/lib/samagotchi/memory_usage.rb +1 -1
- data/lib/samagotchi/model_lookup.rb +75 -0
- data/lib/samagotchi/model_price.rb +4 -10
- data/lib/samagotchi/model_profile.rb +7 -6
- data/lib/samagotchi/model_settings.rb +37 -2
- data/lib/samagotchi/models_command.rb +1 -1
- data/lib/samagotchi/note_command.rb +2 -3
- data/lib/samagotchi/objectives_audit.rb +4 -3
- data/lib/samagotchi/participant_mode.rb +2 -1
- data/lib/samagotchi/participants.rb +2 -2
- data/lib/samagotchi/plugin/api.rb +41 -6
- data/lib/samagotchi/plugin/context.rb +1 -1
- data/lib/samagotchi/plugin/loader.rb +33 -10
- data/lib/samagotchi/plugin/sessions.rb +3 -6
- data/lib/samagotchi/plugin/tool_spec.rb +5 -3
- data/lib/samagotchi/project_env.rb +1 -1
- data/lib/samagotchi/reasoning_history.rb +14 -20
- data/lib/samagotchi/recap_place.rb +27 -0
- data/lib/samagotchi/reminder_carry.rb +1 -1
- data/lib/samagotchi/reply_wait/liveness.rb +38 -0
- data/lib/samagotchi/reply_wait/poll.rb +44 -15
- data/lib/samagotchi/reply_wait/target.rb +113 -0
- data/lib/samagotchi/reply_wait.rb +22 -2
- data/lib/samagotchi/reprefill_meter.rb +45 -0
- data/lib/samagotchi/review_command.rb +1 -1
- data/lib/samagotchi/sampling_settings.rb +9 -16
- data/lib/samagotchi/self_report.rb +36 -37
- data/lib/samagotchi/send_command.rb +17 -23
- data/lib/samagotchi/session.rb +370 -445
- data/lib/samagotchi/session_access/local.rb +12 -11
- data/lib/samagotchi/session_access/remote.rb +22 -6
- data/lib/samagotchi/session_archive_command.rb +2 -2
- data/lib/samagotchi/session_chain.rb +7 -6
- data/lib/samagotchi/session_continue.rb +6 -5
- data/lib/samagotchi/session_delete_command.rb +1 -1
- data/lib/samagotchi/session_field.rb +133 -0
- data/lib/samagotchi/session_inbox.rb +49 -1
- data/lib/samagotchi/session_manager/delivery.rb +254 -0
- data/lib/samagotchi/session_manager/emptiness.rb +139 -0
- data/lib/samagotchi/session_manager/lifecycle.rb +274 -0
- data/lib/samagotchi/session_manager/listing.rb +118 -0
- data/lib/samagotchi/session_manager/removal.rb +190 -0
- data/lib/samagotchi/session_manager/spawn.rb +242 -0
- data/lib/samagotchi/session_manager/worker_command.rb +157 -0
- data/lib/samagotchi/session_manager.rb +28 -1541
- data/lib/samagotchi/session_metrics.rb +8 -5
- data/lib/samagotchi/session_paths.rb +57 -0
- data/lib/samagotchi/session_retention.rb +2 -2
- data/lib/samagotchi/session_row.rb +200 -0
- data/lib/samagotchi/session_setup.rb +15 -12
- data/lib/samagotchi/sessions_command.rb +11 -129
- data/lib/samagotchi/share_command.rb +1 -1
- data/lib/samagotchi/starting_marker.rb +65 -0
- data/lib/samagotchi/steer_cut_after.rb +7 -14
- data/lib/samagotchi/system_one/recorder.rb +49 -0
- data/lib/samagotchi/terminal_ui/attached_loop.rb +6 -26
- data/lib/samagotchi/terminal_ui/exit_lines.rb +1 -1
- data/lib/samagotchi/terminal_ui/join_replay.rb +86 -8
- data/lib/samagotchi/terminal_ui/local_link.rb +2 -2
- data/lib/samagotchi/terminal_ui.rb +5 -7
- data/lib/samagotchi/testing/install.rb +2 -1
- data/lib/samagotchi/testing/sessions.rb +1 -1
- data/lib/samagotchi/thinking.rb +16 -21
- data/lib/samagotchi/token_usage.rb +1 -1
- data/lib/samagotchi/tool_activity.rb +10 -4
- data/lib/samagotchi/tool_declarations.rb +2 -2
- data/lib/samagotchi/tool_output_cut.rb +17 -0
- data/lib/samagotchi/tool_response.rb +5 -3
- data/lib/samagotchi/tool_runner.rb +25 -5
- data/lib/samagotchi/toolkit_command.rb +1 -1
- data/lib/samagotchi/tools/delegate.rb +55 -45
- data/lib/samagotchi/tools/delegate_relay.rb +5 -5
- data/lib/samagotchi/tools/delegate_result.rb +5 -5
- data/lib/samagotchi/tools/delegate_wait.rb +41 -17
- data/lib/samagotchi/tools/index_hint.rb +14 -0
- data/lib/samagotchi/tools/list_sessions.rb +7 -7
- data/lib/samagotchi/tools/registry.rb +28 -11
- data/lib/samagotchi/tools/send_note.rb +4 -6
- data/lib/samagotchi/tools/tool_index.rb +52 -51
- data/lib/samagotchi/tools/tool_surface.rb +22 -8
- data/lib/samagotchi/turn_context.rb +2 -1
- data/lib/samagotchi/turn_stages/context_judge.rb +38 -36
- data/lib/samagotchi/turn_stages/objectives.rb +56 -52
- data/lib/samagotchi/turn_stages/toolkit_suggestion.rb +13 -17
- data/lib/samagotchi/turn_stages/verify_anchors.rb +9 -10
- data/lib/samagotchi/turn_stages/warmup.rb +14 -15
- data/lib/samagotchi/update_command.rb +11 -7
- data/lib/samagotchi/verify_fresh.rb +7 -11
- data/lib/samagotchi/version.rb +1 -1
- data/lib/samagotchi/vision_support.rb +11 -14
- data/lib/samagotchi/web/app.rb +45 -28
- data/lib/samagotchi/web/message_display.rb +57 -7
- data/lib/samagotchi/web/participant_access.rb +3 -3
- data/lib/samagotchi/web/public/activity.js +16 -7
- data/lib/samagotchi/web/public/app.js +29 -8
- data/lib/samagotchi/web/public/bubbles.js +8 -3
- data/lib/samagotchi/web/public/cards_place.js +15 -0
- data/lib/samagotchi/web/public/commands.js +5 -1
- data/lib/samagotchi/web/public/data.js +4 -2
- data/lib/samagotchi/web/public/history_shape.js +220 -0
- data/lib/samagotchi/web/public/recap_stamp.js +17 -0
- data/lib/samagotchi/web/public/reload_check.js +71 -0
- data/lib/samagotchi/web/public/stage_model.js +7 -5
- data/lib/samagotchi/web/public/stage_view.js +7 -3
- data/lib/samagotchi/web/public/stream_handlers.js +8 -2
- data/lib/samagotchi/web/public/timing.js +43 -2
- data/lib/samagotchi/web/public/turn_block.js +215 -30
- data/lib/samagotchi/web/public/turn_drawing.js +43 -0
- data/lib/samagotchi/web/public/turn_events.js +10 -1
- data/lib/samagotchi/web/public/turn_pieces.js +29 -0
- data/lib/samagotchi/web/reload_check_route.rb +95 -0
- data/lib/samagotchi/web/server.rb +4 -2
- data/lib/samagotchi/web/session_access_routes.rb +6 -6
- data/lib/samagotchi/web/session_control.rb +4 -4
- data/lib/samagotchi/web/session_create.rb +3 -3
- data/lib/samagotchi/web/session_hub.rb +9 -17
- data/lib/samagotchi/web/session_show.rb +67 -5
- data/lib/samagotchi/web/session_summary.rb +39 -28
- data/lib/samagotchi/worker.rb +83 -32
- data/lib/samagotchi/worker_boot.rb +184 -0
- data/lib/samagotchi/worker_link.rb +3 -0
- data/lib/samagotchi/worker_signals.rb +1 -1
- data/lib/samagotchi/worker_task_wakes.rb +2 -2
- metadata +32 -4
- data/lib/samagotchi/send_command/wait_target.rb +0 -85
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "file_digest"
|
|
4
|
+
require_relative "installed_bundle"
|
|
5
|
+
require_relative "provenance"
|
|
6
|
+
|
|
7
|
+
module Samagotchi
|
|
8
|
+
module MemoryBundle
|
|
9
|
+
# One bundle memory as a command meets it: which of a few states it is in,
|
|
10
|
+
# computed once from the file (D), its base (B), the bundle's text (I) and
|
|
11
|
+
# the record's entry (R). Derived, never stored. FileActions says what each
|
|
12
|
+
# acting command does in each state.
|
|
13
|
+
#
|
|
14
|
+
# kind, with a source (install, upgrade, remerge, restore, plan):
|
|
15
|
+
# :new not the bundle's, not on disk
|
|
16
|
+
# :user_same not the bundle's, on disk with I's bytes
|
|
17
|
+
# :user_file not the bundle's, other bytes (the user's own file)
|
|
18
|
+
# :missing the bundle's, not on disk
|
|
19
|
+
# :level the bundle's, D == I
|
|
20
|
+
# :pristine never edited (#edited?: D == R's checksum, or with
|
|
21
|
+
# none D == B): the bundle's text as installed
|
|
22
|
+
# :edited edited, D != B, I == B: the user changed it, the
|
|
23
|
+
# bundle didn't
|
|
24
|
+
# :diverged edited, D != B, I != B: both changed it
|
|
25
|
+
# :pristine_no_base no B, never edited (D == R's checksum)
|
|
26
|
+
# :edited_no_base no B, edited (or no checksum to tell); or a B equal
|
|
27
|
+
# to D that the checksum calls edited: no base to
|
|
28
|
+
# merge from
|
|
29
|
+
# :dropped_pristine / :dropped_edited / :dropped_missing the bundle no
|
|
30
|
+
# longer ships it (no I): unedited, edited, gone
|
|
31
|
+
# :unreadable on disk, but it can't be read
|
|
32
|
+
# Edited or not is always the one rule (#edited?, the checksum first);
|
|
33
|
+
# the base then says what the user changed.
|
|
34
|
+
#
|
|
35
|
+
# kind, with no source (status, uninstall, diff): I is unknown, so only
|
|
36
|
+
# :pristine :edited :pristine_no_base :edited_no_base :missing :unreadable,
|
|
37
|
+
# from #edited? alone.
|
|
38
|
+
#
|
|
39
|
+
# mark: :none, :current (a mark this chi wrote) or :legacy (an older
|
|
40
|
+
# chi's, InstalledBundle.legacy_mark?).
|
|
41
|
+
FileState = Data.define(:key, :kind, :mark, :digests, :entry, :paths, :claimants) do
|
|
42
|
+
# Provenance.unchanged?'s answer negated: the one edited rule (checksum
|
|
43
|
+
# first, then the base). A file it can't read counts as edited.
|
|
44
|
+
def edited?
|
|
45
|
+
return false if entry.nil?
|
|
46
|
+
|
|
47
|
+
!Provenance.unchanged?(paths[:current], entry, paths[:base])
|
|
48
|
+
rescue SystemCallError
|
|
49
|
+
true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def marked? = mark != :none
|
|
53
|
+
|
|
54
|
+
# A marked file whose source moved since the mark: the mark speaks of
|
|
55
|
+
# other text than the bundle ships now (Remerge's first question). A mark
|
|
56
|
+
# that names no text (an older chi's) never moved.
|
|
57
|
+
def source_moved?
|
|
58
|
+
marked? && !digests.marked_incoming.nil? && !digests.incoming.nil? && digests.marked_incoming != digests.incoming
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# The other installed bundles that list the file too. Asked lazily: only
|
|
62
|
+
# a dropped file and an uninstall need it (Provenance.claimants reads
|
|
63
|
+
# every record).
|
|
64
|
+
def shared_with = claimants.call
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# The digests of the file's texts, each read once: disk (:unreadable when
|
|
68
|
+
# it can't be read), base, incoming (nil with no source), the record's
|
|
69
|
+
# checksum, and the text a mark speaks of (nil without a mark or for an
|
|
70
|
+
# older chi's mark).
|
|
71
|
+
FileState::Digests = Data.define(:disk, :base, :incoming, :recorded, :marked_incoming)
|
|
72
|
+
|
|
73
|
+
class << FileState
|
|
74
|
+
# @param record [InstalledBundle, nil] the bundle's record
|
|
75
|
+
# @param provenance [Provenance] the record's (for the base path)
|
|
76
|
+
# @param source_dir [String, nil] the bundle's incoming dir; nil: the
|
|
77
|
+
# source-less kinds
|
|
78
|
+
# @param claimants [#call, nil] key => other bundles listing it
|
|
79
|
+
# (Provenance.claimants), called at most once
|
|
80
|
+
# @param shipped [Boolean] false: the bundle no longer ships the key
|
|
81
|
+
# (a dropped kind), whatever its source dir holds by that name
|
|
82
|
+
# @return [FileState]
|
|
83
|
+
def of(key, record:, provenance:, target_dir:, source_dir:, claimants: nil, shipped: true)
|
|
84
|
+
entry = record&.files&.fetch(key, nil)
|
|
85
|
+
paths = { base: provenance.base_path(key), current: File.join(target_dir, key),
|
|
86
|
+
incoming: source_dir && File.join(source_dir, key) }
|
|
87
|
+
mark = mark_of(entry)
|
|
88
|
+
digests = FileState::Digests.new(
|
|
89
|
+
disk: digest(paths[:current]), base: entry ? digest(paths[:base]) : nil,
|
|
90
|
+
incoming: source_dir && shipped ? digest(paths[:incoming]) : nil, recorded: entry && Provenance.recorded_sha(entry[:checksum]),
|
|
91
|
+
marked_incoming: mark == :none ? nil : entry[:incoming_sha]
|
|
92
|
+
)
|
|
93
|
+
shared = nil
|
|
94
|
+
lookup = -> { shared ||= claimants ? claimants.call(key) : [] }
|
|
95
|
+
state = FileState.new(key: key, kind: nil, mark: mark, digests: digests, entry: entry, paths: paths, claimants: lookup)
|
|
96
|
+
state.with(kind: source_dir ? kind_with_source(state) : kind_without_source(state))
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
private
|
|
100
|
+
|
|
101
|
+
def mark_of(entry)
|
|
102
|
+
return :none unless entry && entry[:conflict]
|
|
103
|
+
|
|
104
|
+
InstalledBundle.legacy_mark?(entry) ? :legacy : :current
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def digest(path)
|
|
108
|
+
FileDigest.hex(path)
|
|
109
|
+
rescue SystemCallError
|
|
110
|
+
:unreadable
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def kind_with_source(state)
|
|
114
|
+
d = state.digests
|
|
115
|
+
return not_owned(d) unless state.entry
|
|
116
|
+
return :unreadable if d.disk == :unreadable
|
|
117
|
+
return dropped(state) if d.incoming.nil?
|
|
118
|
+
return :missing if d.disk.nil?
|
|
119
|
+
return :level if d.disk == d.incoming
|
|
120
|
+
return state.edited? ? :edited_no_base : :pristine_no_base if d.base.nil?
|
|
121
|
+
return :pristine unless state.edited?
|
|
122
|
+
# Edited by the one rule, yet equal to its base: the base can't say
|
|
123
|
+
# what the user changed (it isn't the text the record vouches for),
|
|
124
|
+
# so there is none to merge from.
|
|
125
|
+
return :edited_no_base if d.disk == d.base
|
|
126
|
+
|
|
127
|
+
d.incoming == d.base ? :edited : :diverged
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def kind_without_source(state)
|
|
131
|
+
d = state.digests
|
|
132
|
+
return :unreadable if d.disk == :unreadable
|
|
133
|
+
return :missing if d.disk.nil?
|
|
134
|
+
return state.edited? ? :edited_no_base : :pristine_no_base if d.base.nil?
|
|
135
|
+
|
|
136
|
+
state.edited? ? :edited : :pristine
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def not_owned(digests)
|
|
140
|
+
return :new if digests.disk.nil?
|
|
141
|
+
|
|
142
|
+
digests.disk == digests.incoming ? :user_same : :user_file
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def dropped(state)
|
|
146
|
+
return :dropped_missing if state.digests.disk.nil?
|
|
147
|
+
|
|
148
|
+
state.edited? ? :dropped_edited : :dropped_pristine
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
@@ -93,7 +93,8 @@ module Samagotchi
|
|
|
93
93
|
return nil unless bundle.plugin
|
|
94
94
|
|
|
95
95
|
file = bundle.plugin.file
|
|
96
|
-
{ file: file, sha256: copy(provenance.plugin_path(bundle), File.join(dir, file), bundle.plugin.sha256)
|
|
96
|
+
{ file: file, sha256: copy(provenance.plugin_path(bundle), File.join(dir, file), bundle.plugin.sha256),
|
|
97
|
+
required: bundle.manifest.plugin_required }
|
|
97
98
|
end
|
|
98
99
|
private_class_method :plugin
|
|
99
100
|
|
|
@@ -50,6 +50,11 @@ module Samagotchi
|
|
|
50
50
|
# as Manifest reads them (settings nil when
|
|
51
51
|
# the manifest said nothing of them)
|
|
52
52
|
# file_descriptions file key => the memory's description
|
|
53
|
+
# plugin_required plugin: required: true (a guardrail plugin:
|
|
54
|
+
# one that fails to load denies every tool
|
|
55
|
+
# call): the record's (PluginRef#required,
|
|
56
|
+
# recorded at install) or the kept manifest's,
|
|
57
|
+
# so a lost or edited kept file keeps it
|
|
53
58
|
# includes a profile's recorded members (the record's
|
|
54
59
|
# identity, never the kept file's), nil for a plain bundle
|
|
55
60
|
# unknown_keys the kept manifest's keys this chi doesn't know
|
|
@@ -59,7 +64,7 @@ module Samagotchi
|
|
|
59
64
|
class InstalledManifest < Data.define(:name, :version, :requires_chi, :trust_level, :description, :hooks, :needs,
|
|
60
65
|
:script_names, :context_providers, :block_renderers, :session_settings,
|
|
61
66
|
:session_setting_types, :settings, :setting_types, :file_descriptions,
|
|
62
|
-
:includes, :unknown_keys, :floor_keys, :problems, :origin)
|
|
67
|
+
:plugin_required, :includes, :unknown_keys, :floor_keys, :problems, :origin)
|
|
63
68
|
# The key problems names the kept file's standing under.
|
|
64
69
|
KEPT_FILE = "manifest.yml"
|
|
65
70
|
# How many manifests the cache holds before it starts again.
|
|
@@ -133,6 +138,7 @@ module Samagotchi
|
|
|
133
138
|
session_settings: session.session_settings, session_setting_types: session.session_setting_types,
|
|
134
139
|
settings: settings.settings, setting_types: settings.setting_types,
|
|
135
140
|
file_descriptions: pick.call("files", kept.file_descriptions, mirrored.file_descriptions),
|
|
141
|
+
plugin_required: kept.plugin&.dig(:required) == true || mirrored.plugin_required,
|
|
136
142
|
includes: bundle.includes,
|
|
137
143
|
unknown_keys: kept.unknown_keys.map(&:to_s), floor_keys: floors(kept), problems: problems.freeze, origin: :kept)
|
|
138
144
|
end
|
|
@@ -168,6 +174,7 @@ module Samagotchi
|
|
|
168
174
|
settings: list(raw["settings"]),
|
|
169
175
|
setting_types: types(raw["setting_types"]),
|
|
170
176
|
file_descriptions: file_descriptions(bundle.files),
|
|
177
|
+
plugin_required: bundle.plugin&.required == true,
|
|
171
178
|
includes: bundle.includes, unknown_keys: [], floor_keys: {}, problems: problems.freeze, origin: :record)
|
|
172
179
|
end
|
|
173
180
|
|