samagotchi 0.146.0 → 0.148.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 +34 -1
- data/README.md +2 -2
- data/docs/architecture.md +14 -5
- data/docs/bundles.md +26 -16
- data/docs/cli.md +6 -2
- data/docs/configuration.md +19 -4
- data/docs/guardrails.md +25 -4
- data/docs/sessions.md +2 -2
- data/docs/system-one.md +1 -1
- data/lib/samagotchi/answer_tail.rb +1 -1
- data/lib/samagotchi/bundles/coordinator/guardrails/merge.yml +21 -0
- data/lib/samagotchi/bundles/coordinator/manifest.yml +7 -5
- data/lib/samagotchi/bundles/coordinator/plugin.rb +2 -1
- data/lib/samagotchi/bundles/coordinator/skill_coordinator.md +35 -13
- data/lib/samagotchi/bundles/system/manifest.yml +1 -1
- data/lib/samagotchi/config.rb +5 -0
- data/lib/samagotchi/guardrail_wiring.rb +11 -6
- data/lib/samagotchi/guardrails/approvals.rb +3 -1
- data/lib/samagotchi/guardrails/rules.rb +6 -1
- data/lib/samagotchi/guardrails/verdict.rb +21 -1
- data/lib/samagotchi/guardrails_command.rb +47 -3
- data/lib/samagotchi/run_options.rb +1 -0
- data/lib/samagotchi/send_command.rb +2 -1
- data/lib/samagotchi/session_chain.rb +91 -8
- data/lib/samagotchi/session_commands.rb +1 -1
- data/lib/samagotchi/session_continue.rb +3 -2
- data/lib/samagotchi/system_one/record.rb +17 -3
- data/lib/samagotchi/version.rb +1 -1
- data/lib/samagotchi/web/app.rb +1 -1
- data/lib/samagotchi/web/auto_update.rb +60 -5
- data/lib/samagotchi/web/public/app.js +5 -16
- data/lib/samagotchi/web/public/update_notice.js +22 -11
- data/lib/samagotchi/web/public/update_sheet.js +4 -1
- data/lib/samagotchi/web/session_access_routes.rb +1 -1
- data/lib/samagotchi/web/session_hub.rb +17 -4
- metadata +2 -1
|
@@ -17,12 +17,7 @@ export function mergeVersionState(current = {}, frame = {}) {
|
|
|
17
17
|
if (has(frame, "update_blocked")) next.updateBlocked = known(frame.update_blocked) ? frame.update_blocked : null;
|
|
18
18
|
if (has(frame, "auto")) next.auto = frame.auto === "install" ? "install" : "off";
|
|
19
19
|
if (has(frame, "restart")) next.restart = frame.restart === "never" ? "never" : "idle";
|
|
20
|
-
|
|
21
|
-
// version an automatic one installs, while it hasn't failed.
|
|
22
|
-
const run = frame.chi_update;
|
|
23
|
-
if (run && run.operation === "install" && known(run.version)) {
|
|
24
|
-
next.autoInstall = run.auto === true && run.state !== "failed" ? run.version : null;
|
|
25
|
-
}
|
|
20
|
+
if (has(frame, "auto_offers")) next.autoOffers = known(frame.auto_offers) ? frame.auto_offers : null;
|
|
26
21
|
return next;
|
|
27
22
|
}
|
|
28
23
|
|
|
@@ -53,22 +48,23 @@ export function newerVersion(a, b) {
|
|
|
53
48
|
// The toast for the versions as the page knows them, or null:
|
|
54
49
|
// - loaded ≠ served: chi web restarted on another version; reload the page;
|
|
55
50
|
// - installed newer than served: chi web runs an older chi than installed;
|
|
56
|
-
// restart its workers or chi web; not
|
|
57
|
-
//
|
|
58
|
-
//
|
|
51
|
+
// restart its workers or chi web; not with update.auto: install and
|
|
52
|
+
// update.restart: idle (and not blocked), where chi web restarts them by
|
|
53
|
+
// itself and pushes how it went, however that chi got installed, unless
|
|
54
|
+
// chi web says it won't or has been held for long (+autoOffers+);
|
|
59
55
|
// - available newer than served: install it, unless the install is blocked;
|
|
60
56
|
// with update.auto: install (and not blocked) chi web installs it by itself
|
|
61
57
|
// once no turn runs: the notice says so, with no Update button.
|
|
62
58
|
// Each has a key; one in +shown+ (a Set: what this tab already showed, as
|
|
63
59
|
// every reconnect's snapshot says it again) is not shown twice.
|
|
64
60
|
// @return {{key, text, reload: boolean} | null}
|
|
65
|
-
export function versionNotice({ loaded, served, installed, available, updateBlocked, auto, restart,
|
|
61
|
+
export function versionNotice({ loaded, served, installed, available, updateBlocked, auto, restart, autoOffers,
|
|
66
62
|
shown = new Set() } = {}) {
|
|
67
63
|
let notice = null;
|
|
68
64
|
if (known(loaded) && known(served) && loaded !== served) {
|
|
69
65
|
notice = { key: `reload:${served}`, text: `chi was updated to ${served}`, reload: true };
|
|
70
66
|
} else if (newerVersion(installed, served)) {
|
|
71
|
-
const restartsByItself = auto === "install" && restart !== "never" &&
|
|
67
|
+
const restartsByItself = auto === "install" && restart !== "never" && !updateBlocked && autoOffers !== installed;
|
|
72
68
|
if (!restartsByItself) {
|
|
73
69
|
notice = {
|
|
74
70
|
key: `installed:${installed}`,
|
|
@@ -101,6 +97,21 @@ export function versionNotice({ loaded, served, installed, available, updateBloc
|
|
|
101
97
|
return notice && !shown.has(notice.key) ? notice : null;
|
|
102
98
|
}
|
|
103
99
|
|
|
100
|
+
// The toast's words for an update operation's frame, or null: what runs and how
|
|
101
|
+
// it ended, for a tab whose sheet isn't open. An automatic run's worker passes
|
|
102
|
+
// say something only when one fails (the run ends in the Reload toast); a done
|
|
103
|
+
// install leaves it to the version toast; a snapshot repeats no ending.
|
|
104
|
+
export function updateFrameToast(data, { wasOpen = false, snapshot = false } = {}) {
|
|
105
|
+
if (wasOpen) return null;
|
|
106
|
+
if (data.auto && data.operation === "workers" && data.state !== "failed") return null;
|
|
107
|
+
const label = `${data.auto ? "Automatic " : ""}${data.operation === "install" ? "chi update" : "worker restart"}`
|
|
108
|
+
.replace(/^./, (c) => c.toUpperCase());
|
|
109
|
+
if (data.state === "running") return `${label} in progress`;
|
|
110
|
+
if (snapshot || !["done", "failed"].includes(data.state)) return null;
|
|
111
|
+
if (data.operation === "install" && data.state === "done") return null;
|
|
112
|
+
return `${label} ${data.state}`;
|
|
113
|
+
}
|
|
114
|
+
|
|
104
115
|
// The info bar's badge for the open session's worker when it runs an older
|
|
105
116
|
// chi than the newest installed (or than chi web, while that is unknown),
|
|
106
117
|
// else null. A worker with the "restart" feature offers Restart; an older
|
|
@@ -45,9 +45,10 @@ function statusText(model) {
|
|
|
45
45
|
|
|
46
46
|
// Both restarts, once a newer chi is installed (an install done here, or the
|
|
47
47
|
// installed notice's toast) and nothing runs: either result keeps the other in reach.
|
|
48
|
+
// Not on an automatic run: it restarts them by itself.
|
|
48
49
|
function restartActions(model) {
|
|
49
50
|
const busy = ["starting", "running", "restarting"].includes(model.state);
|
|
50
|
-
if (!model.restartable || busy) return nothing;
|
|
51
|
+
if (!model.restartable || model.auto || busy) return nothing;
|
|
51
52
|
return html`<button type="button" class="ghost" data-act="restart-workers">Restart workers</button>
|
|
52
53
|
<button type="button" class="ghost" data-act="restart-web">Restart chi web</button>`;
|
|
53
54
|
}
|
|
@@ -125,6 +126,8 @@ export function createUpdateSheet({ dialog, update, restartWorkers, restartWeb }
|
|
|
125
126
|
model = {
|
|
126
127
|
...model,
|
|
127
128
|
...data,
|
|
129
|
+
// A frame names auto only when it is true: this run's word, not the last one's.
|
|
130
|
+
auto: data.auto === true,
|
|
128
131
|
rows: Array.isArray(data.rows) ? data.rows : [],
|
|
129
132
|
};
|
|
130
133
|
if (data.operation === "install" && data.state === "done") restartable = true;
|
|
@@ -274,7 +274,7 @@ module Samagotchi
|
|
|
274
274
|
model_name: session_access.show(id).model_name,
|
|
275
275
|
default_model: ModelProfile.default_model_name,
|
|
276
276
|
parent_strategy: strategy_json(session_access.parent_strategy(id)),
|
|
277
|
-
**(@hub&.chi_state || { version: VERSION, installed: nil, available: nil, update_blocked: nil, auto: "off", restart: "idle" }) })
|
|
277
|
+
**(@hub&.chi_state || { version: VERSION, installed: nil, available: nil, update_blocked: nil, auto: "off", restart: "idle", auto_offers: nil }) })
|
|
278
278
|
rescue SessionManager::OwnedByTUI => e
|
|
279
279
|
owned_by_tui(e)
|
|
280
280
|
rescue SessionAccess::Refused => e
|
|
@@ -41,8 +41,7 @@ module Samagotchi
|
|
|
41
41
|
|
|
42
42
|
# What a subscriber gets: `session` with {session: summary} for an
|
|
43
43
|
# upsert, `session_gone` with {id:} for a removal, `chi` with
|
|
44
|
-
#
|
|
45
|
-
# state changes. seq is monotonic per
|
|
44
|
+
# the #chi_state fields when chi version state changes. seq is monotonic per
|
|
46
45
|
# hub, for the log's sake: there is no replay.
|
|
47
46
|
Event = Struct.new(:type, :seq, :data, keyword_init: true)
|
|
48
47
|
|
|
@@ -76,7 +75,7 @@ module Samagotchi
|
|
|
76
75
|
# @param installed_versions [#newest] what is installed (InstalledVersions)
|
|
77
76
|
# @param update_auto [String] update.auto, said in the chi state (the page's wording)
|
|
78
77
|
# @param update_restart [String] update.restart, said beside it (whether
|
|
79
|
-
#
|
|
78
|
+
# a newer installed chi restarts by itself: no Restart toast)
|
|
80
79
|
def initialize(state_dir:, manager: SessionManager, now: nil, scan_interval: SCAN_INTERVAL,
|
|
81
80
|
full_probe_interval: FULL_PROBE_INTERVAL, installed_versions: InstalledVersions.new,
|
|
82
81
|
update_auto: Config.get("update.auto"), update_restart: Config.get("update.restart"))
|
|
@@ -87,6 +86,7 @@ module Samagotchi
|
|
|
87
86
|
@installed = nil
|
|
88
87
|
@available = nil
|
|
89
88
|
@update_blocked = nil
|
|
89
|
+
@auto_offers = nil
|
|
90
90
|
@update_state = nil
|
|
91
91
|
@manager = manager
|
|
92
92
|
@now = now || -> { Process.clock_gettime(Process::CLOCK_MONOTONIC) }
|
|
@@ -164,7 +164,7 @@ module Samagotchi
|
|
|
164
164
|
def chi_state
|
|
165
165
|
@monitor.synchronize do
|
|
166
166
|
{ version: VERSION, installed: @installed, available: @available, update_blocked: @update_blocked,
|
|
167
|
-
auto: @update_auto, restart: @update_restart }
|
|
167
|
+
auto: @update_auto, restart: @update_restart, auto_offers: @auto_offers }
|
|
168
168
|
end
|
|
169
169
|
end
|
|
170
170
|
|
|
@@ -180,6 +180,19 @@ module Samagotchi
|
|
|
180
180
|
nil
|
|
181
181
|
end
|
|
182
182
|
|
|
183
|
+
# AutoUpdate won't (or hasn't, for long) restart onto +version+ by itself:
|
|
184
|
+
# the page offers the restarts for it, in spite of update.auto. In memory:
|
|
185
|
+
# AutoUpdate says it again after a chi web restart.
|
|
186
|
+
def auto_offer_restart(version)
|
|
187
|
+
@monitor.synchronize do
|
|
188
|
+
next if @auto_offers == version
|
|
189
|
+
|
|
190
|
+
@auto_offers = version
|
|
191
|
+
emit("chi", chi_state)
|
|
192
|
+
end
|
|
193
|
+
nil
|
|
194
|
+
end
|
|
195
|
+
|
|
183
196
|
# Publish the owner-triggered update's progress or result for current
|
|
184
197
|
# tabs, and retain the latest state for a reconnect's snapshot.
|
|
185
198
|
def publish_update(state:, rows:, progress: nil, operation: nil, version: nil, auto: false)
|
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.
|
|
4
|
+
version: 0.148.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dmitry Dedov
|
|
@@ -241,6 +241,7 @@ files:
|
|
|
241
241
|
- lib/samagotchi/bundles/codex-peer/scripts/chi-peer-SKILL.md
|
|
242
242
|
- lib/samagotchi/bundles/codex-peer/scripts/pair
|
|
243
243
|
- lib/samagotchi/bundles/codex-peer/skill_codex_peer.md
|
|
244
|
+
- lib/samagotchi/bundles/coordinator/guardrails/merge.yml
|
|
244
245
|
- lib/samagotchi/bundles/coordinator/manifest.yml
|
|
245
246
|
- lib/samagotchi/bundles/coordinator/plugin.rb
|
|
246
247
|
- lib/samagotchi/bundles/coordinator/skill_coordinator.md
|