strom-research 1.22.0-beta.3 → 1.22.0-beta.4
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.
- package/CHANGELOG.cs.md +4 -1
- package/CHANGELOG.de.md +5 -1
- package/CHANGELOG.md +4 -1
- package/assets/lang/cs.json +27 -0
- package/assets/lang/de.json +27 -0
- package/dist/brief/brief.js +19 -1
- package/dist/brief/history.js +217 -0
- package/dist/cli/menu-links.js +33 -0
- package/dist/cli/registry.js +3 -2
- package/dist/cli/ui.js +17 -0
- package/dist/commands/checks.js +4 -4
- package/dist/commands/connectors.js +5 -0
- package/dist/commands/history.js +481 -0
- package/dist/commands/index.js +1 -0
- package/dist/commands/links.js +23 -0
- package/dist/commands/session.js +40 -6
- package/dist/commands/setup.js +22 -0
- package/dist/commands/tasks.js +11 -3
- package/dist/core/config.js +11 -0
- package/dist/core/integrity.js +70 -2
- package/dist/core/links.js +9 -2
- package/dist/core/live.js +161 -5
- package/dist/core/pack.js +23 -1
- package/dist/core/pagecheck.js +437 -0
- package/dist/core/pastevents.js +1124 -0
- package/dist/core/phrases.js +10 -0
- package/dist/core/queue.js +25 -5
- package/dist/core/session.js +7 -0
- package/dist/core/tree.js +15 -1
- package/dist/core/web.js +5 -1
- package/dist/gedcom/export.js +42 -7
- package/dist/gedcom/lines.js +5 -1
- package/package.json +1 -1
package/CHANGELOG.cs.md
CHANGED
|
@@ -7,7 +7,7 @@ Změny každé verze ve zkratce. Úplné poznámky a instalační řádky jsou n
|
|
|
7
7
|
|
|
8
8
|
## 1.22.0
|
|
9
9
|
|
|
10
|
-
*Připravuje se: bety do 1.22.0-beta.
|
|
10
|
+
*Připravuje se: bety do 1.22.0-beta.4. Oddíl bude úplný s vydáním.*
|
|
11
11
|
|
|
12
12
|
- **Jméno jednou v tom, co čeká.** Úkol k materiálu poslanému z aplikace Strom jmenoval ve widgetu a na stránce
|
|
13
13
|
telefonu každého člověka dvakrát (podruhé v hranatých závorkách) a jeho text bez jmen nechal prázdné závorky; menu,
|
|
@@ -26,6 +26,9 @@ Změny každé verze ve zkratce. Úplné poznámky a instalační řádky jsou n
|
|
|
26
26
|
tam, kde skončil; když mlčí dál, hned skončí. Takový výpadek už nezmenšuje dávky čtení.
|
|
27
27
|
- **Brána týdne předplatného pustí víc sezení za sebou.** Když jednou čeká na náskok, pustí znovu až se dvěma body navíc
|
|
28
28
|
(při 15: 17), místo jednoho sezení po každém čekání.
|
|
29
|
+
- **Experiment: co předek zažil.** Pokusné a ve výchozím stavu vypnuté: události v místech stromu – dějiny kraje ze
|
|
30
|
+
stránek, které strom sám stáhl a ověřil, místní události z přečtených záznamů – ukáže aplikace Strom. Zapnout ho
|
|
31
|
+
může jen člověk; dokud je vypnuté, nic se nehledá.
|
|
29
32
|
|
|
30
33
|
## 1.21.0
|
|
31
34
|
|
package/CHANGELOG.de.md
CHANGED
|
@@ -7,7 +7,7 @@ Die Änderungen jeder Version in Kürze. Die vollständigen Hinweise und die Ins
|
|
|
7
7
|
|
|
8
8
|
## 1.22.0
|
|
9
9
|
|
|
10
|
-
*In Vorbereitung: die Betas bis 1.22.0-beta.
|
|
10
|
+
*In Vorbereitung: die Betas bis 1.22.0-beta.4. Der Abschnitt ist mit dem Release vollständig.*
|
|
11
11
|
|
|
12
12
|
- **Jeder Name einmal in dem, was wartet.** Eine Aufgabe zu Material, das aus der Strom-App gesendet wurde, nannte im
|
|
13
13
|
Widget und auf der Seite des Telefons jede Person zweimal (das zweite Mal in eckigen Klammern), und ihr Text ohne
|
|
@@ -30,6 +30,10 @@ Die Änderungen jeder Version in Kürze. Die vollständigen Hinweise und die Ins
|
|
|
30
30
|
Ausfall verkleinert die Lesestapel nicht mehr.
|
|
31
31
|
- **Das Tor der Abo-Woche lässt mehrere Sitzungen hintereinander laufen.** Wartet es einmal auf Vorsprung, lässt es
|
|
32
32
|
erst mit zwei Punkten mehr wieder los (bei 15: 17), statt einer Sitzung nach jedem Warten.
|
|
33
|
+
- **Ein Experiment: was die Vorfahren erlebten.** Experimentell und standardmäßig aus: die Ereignisse an den Orten des
|
|
34
|
+
Stammbaums – die Geschichte einer Region aus Seiten, die strom selbst geladen und geprüft hat, örtliche Ereignisse
|
|
35
|
+
aus gelesenen Einträgen – zeigt die Strom-App. Einschalten kann es nur ein Mensch; solange es aus ist, wird nichts
|
|
36
|
+
gesucht.
|
|
33
37
|
|
|
34
38
|
## 1.21.0
|
|
35
39
|
|
package/CHANGELOG.md
CHANGED
|
@@ -7,7 +7,7 @@ The changes of each version in short. The full notes and the install lines are o
|
|
|
7
7
|
|
|
8
8
|
## 1.22.0
|
|
9
9
|
|
|
10
|
-
*In preparation: the betas up to 1.22.0-beta.
|
|
10
|
+
*In preparation: the betas up to 1.22.0-beta.4. The section is complete with the release.*
|
|
11
11
|
|
|
12
12
|
- **Each name once in what waits.** A task for material sent from the Strom app named each person twice in the
|
|
13
13
|
widget and on the phone's page (the second time in brackets), and its text without names kept empty brackets; the
|
|
@@ -28,6 +28,9 @@ The changes of each version in short. The full notes and the install lines are o
|
|
|
28
28
|
smaller.
|
|
29
29
|
- **The gate of the subscription's week lets several sessions run in a row.** Once it waits for points in hand, it goes again only
|
|
30
30
|
with two more (at 15: 17), instead of one session after every wait.
|
|
31
|
+
- **An experiment: what the ancestors lived through.** Experimental and off by default: the events at the places of
|
|
32
|
+
the tree — the history of a region from pages strom downloaded and checked itself, local events from the records
|
|
33
|
+
read — shown by the Strom app. Only a person turns it on; while it is off, nothing is looked for.
|
|
31
34
|
|
|
32
35
|
## 1.21.0
|
|
33
36
|
|
package/assets/lang/cs.json
CHANGED
|
@@ -544,6 +544,7 @@
|
|
|
544
544
|
"ui.run.stop.user": "zastaveno ručně",
|
|
545
545
|
"ui.run.stop.time": "časový limit",
|
|
546
546
|
"ui.run.stop.empty": "žádné otevřené úkoly",
|
|
547
|
+
"ui.run.stop.history": "dějiny míst počkají do zítřka: bez podmínky (run.gate) jedno sezení denně, nic jiného k práci",
|
|
547
548
|
"ui.run.stop.asleep": "do {at} není co dělat – zbylé úkoly potřebují {host}, který teď neodpovídá",
|
|
548
549
|
"ui.run.stop.problems": "doklady mají problém – strom check",
|
|
549
550
|
"ui.run.stop.denied": "agent nesměl spouštět strom – nepustila ho jeho oprávnění nebo sandbox; nic dalšího se nespustilo",
|
|
@@ -721,6 +722,16 @@
|
|
|
721
722
|
"archive.held": "odloženo: výzkum je Archiv Stromu (data přicházejí z aplikace Strom); do fronty se vrátí, až se zapne práce s agentem",
|
|
722
723
|
"archive.removed": "odebráno v aplikaci Strom",
|
|
723
724
|
"archive.wait": "Rozhodnutí o stahování z archivu {title}",
|
|
725
|
+
"history.why.archive": "Dokud je výzkum vedený jako archiv, nic se nehledá.",
|
|
726
|
+
"history.why.held": "Události regionu {region} hledá jiný výzkum na tomto počítači.",
|
|
727
|
+
"history.places.what": "Místa údajů pro dějiny předků ({n}): regiony, kam které patřilo, i s roky",
|
|
728
|
+
"history.places.why": "události dějin (války, epidemie, sčítání lidu, změny státu) se ukazují u míst údajů podle regionů, kam patřila – pokus",
|
|
729
|
+
"history.places.done": "každé místo přiřazené k regionům i s roky, nebo označené jako nedohledané",
|
|
730
|
+
"history.region.what": "Události dějin v regionu {region}: války, epidemie, sčítání lidu, změny státu, vystěhovalectví",
|
|
731
|
+
"history.region.where": "encyklopedie, státní instituce, archivy, Wikipedie v jazyce regionu s jejími odkazy",
|
|
732
|
+
"history.region.why": "co předkové zažili, ukázané u jejich životů – pokus",
|
|
733
|
+
"history.region.done": "důležité události období nalezené, každá ze stránky, kterou strom sám přečetl (nanejvýš asi 60); katalog regionu označený jako hotový",
|
|
734
|
+
"history.region.finished": "události regionu {region} jsou hotové",
|
|
724
735
|
"review.reread.what": "Přečíst znovu modelem {model}, o co se opírají údaje osoby {name}: {list}{more}",
|
|
725
736
|
"review.reread.why": "tyto zápisy četl jen jiný model; {model} je ten, kterým uživatel čte teď ({research})",
|
|
726
737
|
"review.reread.done": "zápis každého údaje přečtený naslepo modelem {model} (strom read M… --blind): shoda → poznámka u údaje; rozdíl → rozpor s oběma čteními",
|
|
@@ -1155,6 +1166,10 @@
|
|
|
1155
1166
|
"ui.recent.more": "… a další: {n}",
|
|
1156
1167
|
"ui.recent.morechanges": "(a další změny: {n})",
|
|
1157
1168
|
"ui.history.none": "historie je zatím prázdná",
|
|
1169
|
+
"ui.history.past.hidden": "Skryto: {event} – {where}",
|
|
1170
|
+
"ui.history.past.shown": "Znovu zobrazeno: {event} – {where}",
|
|
1171
|
+
"ui.history.past.same": "Beze změny: {event} – {where}",
|
|
1172
|
+
"ui.history.past.redo": "Události regionu {region} se budou hledat znovu (nalezené zůstávají).",
|
|
1158
1173
|
"ui.browse.plan": "Co agent udělá dál",
|
|
1159
1174
|
"ui.review.new": "{name} — {n, plural, one {# nový úkol} few {# nové úkoly} other {# nových úkolů}}:",
|
|
1160
1175
|
"ui.review.nothing": "{name} — nic nového k revizi",
|
|
@@ -1704,6 +1719,7 @@
|
|
|
1704
1719
|
"ui.archives.agentbrowser.off": "Vrátit prohlížeč jen pro archivy přes prohlížeč?",
|
|
1705
1720
|
"ui.consent.remote": "Spouštět sezení Claude Code, která strom otevírá, se vzdáleným ovládáním (Remote Control), aby je šlo sledovat a řídit z claude.ai nebo z aplikace Claude v telefonu?",
|
|
1706
1721
|
"ui.consent.addons": "Dovolit agentovi při samostatné práci načíst osobní doplňky z jeho nastavení (skilly, pluginy, MCP servery – třeba i poštu nebo dokumenty) jako v chatu? Pracuje přitom bez dozoru.",
|
|
1722
|
+
"ui.consent.history": "Hledat události dějin v místech všech výzkumů na tomto počítači – války, epidemie, sčítání, změny státu? Experiment: agent je hledá, jen když rodinný výzkum nemá co dělat, a stojí to jeho čas i čerpání předplatného.",
|
|
1707
1723
|
"ui.consent.effort": "Nastavit sezením {agent}, která spouští strom, hloubku uvažování {effort}? Vyšší hloubka uvažování (high, xhigh) rychleji spotřebuje limity předplatného.",
|
|
1708
1724
|
"ui.consent.webPerHost": "Dovolit vlastnímu webovému nástroji agenta až {n, plural, one {# požadavek} few {# požadavky} other {# požadavků}} na jeden web (jeho servery a zrcadla dohromady) v sezení (nyní {now})? Více požadavků víc zatěžuje web; více stránek jednoho webu je šetrnější stahovat přes konektor.",
|
|
1709
1725
|
"ui.consent.effort.run": "Spustit samostatnou práci {agent} pro tento běh s hloubkou uvažování {effort}, vyšší než v nastavení ({now})? Vyšší hloubka uvažování (high, xhigh) rychleji spotřebuje limity předplatného.",
|
|
@@ -2654,6 +2670,17 @@
|
|
|
2654
2670
|
"ui.archives.permissions.title": "Archivy stahovačů na tomto počítači – co platí pro jejich snímky:",
|
|
2655
2671
|
"ui.archives.state.way": "{way}, rozhodnuto {date}",
|
|
2656
2672
|
"ui.link.archive.none": "O tomto archivu tu není co rozhodnout. Nic se nestalo.",
|
|
2673
|
+
"ui.experiments.link": "Hledání událostí dějin se zapíná jen v terminálu, který otevře odkaz.",
|
|
2674
|
+
"ui.link.what.experiment.history": "hledat události dějin v místech tohoto stromu – války, epidemie, sčítání, změny státu",
|
|
2675
|
+
"ui.link.experiment.note": "Experiment: hledá se jen tehdy, když rodinný výzkum nemá co dělat, nejvýš jedno sezení denně do {minutes} minut.",
|
|
2676
|
+
"ui.link.experiment.note.gate": "Experiment: hledá se jen tehdy, když rodinný výzkum nemá co dělat; kdy, rozhoduje brána běhů, sezení trvá nejvýš {minutes} minut.",
|
|
2677
|
+
"ui.link.experiment.all": "Zapíná se v nastavení tohoto počítače: platí pro všechny výzkumy na něm (každý jde vypnout zvlášť).",
|
|
2678
|
+
"ui.link.experiment.on.done": "Hledání událostí dějin je pro tento výzkum zapnuté.",
|
|
2679
|
+
"ui.link.experiment.on.already": "Hledání událostí dějin je pro tento výzkum zapnuté už. Nic se nestalo.",
|
|
2680
|
+
"ui.link.experiment.off.done": "Hledání událostí dějin je pro tento výzkum vypnuté; co už bylo nalezeno, zůstává.",
|
|
2681
|
+
"ui.link.experiment.off.already": "Hledání událostí dějin je pro tento výzkum vypnuté už. Nic se nestalo.",
|
|
2682
|
+
"ui.link.experiment.archive": "Dokud je výzkum vedený jako archiv, události dějin se nehledají. Nic se nestalo.",
|
|
2683
|
+
"ui.link.experiment.waiting": "Na tomto výzkumu se na tomto počítači nepracuje, a tak se události dějin nehledají. Nic se nestalo.",
|
|
2657
2684
|
"ui.error.archive.permission": "stahování snímků z archivu {title} ({hosts}) čeká na rozhodnutí – podmínky archivu automatické stahování omezují; z archivu se nic nestahovalo",
|
|
2658
2685
|
"ui.error.archive.permission.new": "stahování snímků z archivu {title} ({hosts}) čeká na rozhodnutí – čtení podmínek stahovačem zatím nikdo nepotvrdil; z archivu se nic nestahovalo",
|
|
2659
2686
|
"ui.error.archive.permission.hint": "rozhodnout v menu strom (Co čeká), nebo v terminálu: strom allow archive {host} --way {ways}",
|
package/assets/lang/de.json
CHANGED
|
@@ -544,6 +544,7 @@
|
|
|
544
544
|
"ui.run.stop.user": "von Hand angehalten",
|
|
545
545
|
"ui.run.stop.time": "Zeitlimit",
|
|
546
546
|
"ui.run.stop.empty": "keine offenen Aufgaben",
|
|
547
|
+
"ui.run.stop.history": "die Geschichte der Orte wartet bis morgen: ohne Bedingung (run.gate) eine Sitzung am Tag, sonst nichts zu tun",
|
|
547
548
|
"ui.run.stop.asleep": "bis {at} nichts zu tun – die übrigen Aufgaben brauchen {host}, der gerade nicht antwortet",
|
|
548
549
|
"ui.run.stop.problems": "die Belege haben Probleme – strom check",
|
|
549
550
|
"ui.run.stop.denied": "der Agent durfte strom nicht starten – seine Berechtigungen oder seine Sandbox ließen es nicht zu; nichts weiter wurde gestartet",
|
|
@@ -721,6 +722,16 @@
|
|
|
721
722
|
"archive.held": "zurückgestellt: die Forschung ist ein Strom-Archiv (die Daten kommen aus der Strom-App); zurück in der Warteschlange, wenn die Arbeit mit einem Agenten eingeschaltet wird",
|
|
722
723
|
"archive.removed": "in der Strom-App entfernt",
|
|
723
724
|
"archive.wait": "Entscheidung über das Herunterladen aus dem Archiv {title}",
|
|
725
|
+
"history.why.archive": "Solange die Forschung als Archiv geführt wird, wird nichts gesucht.",
|
|
726
|
+
"history.why.held": "Die Ereignisse von {region} sucht eine andere Forschung auf diesem Computer.",
|
|
727
|
+
"history.places.what": "Die Orte der Angaben für die Geschichte der Vorfahren ({n}): zu welchen Regionen jeder gehörte, mit den Jahren",
|
|
728
|
+
"history.places.why": "die Ereignisse der Geschichte (Kriege, Epidemien, Volkszählungen, Wechsel des Staates) erscheinen an den Orten der Angaben nach den Regionen, zu denen sie gehörten – ein Experiment",
|
|
729
|
+
"history.places.done": "jeder Ort seinen Regionen mit den Jahren zugeordnet oder als nicht auffindbar vermerkt",
|
|
730
|
+
"history.region.what": "Ereignisse der Geschichte in {region}: Kriege, Epidemien, Volkszählungen, Wechsel des Staates, Auswanderung",
|
|
731
|
+
"history.region.where": "Enzyklopädien, staatliche Institutionen, Archive, die Wikipedia in der Sprache der Region mit ihren Belegen",
|
|
732
|
+
"history.region.why": "was die Vorfahren erlebten, bei ihren Lebensläufen gezeigt – ein Experiment",
|
|
733
|
+
"history.region.done": "die wichtigen Ereignisse des Zeitraums gefunden, jedes von einer Seite, die strom selbst gelesen hat (höchstens etwa 60); der Katalog der Region als fertig vermerkt",
|
|
734
|
+
"history.region.finished": "die Ereignisse von {region} sind fertig",
|
|
724
735
|
"review.reread.what": "Mit {model} neu lesen, worauf die Angaben von {name} beruhen: {list}{more}",
|
|
725
736
|
"review.reread.why": "diese Einträge hat nur ein anderes Modell gelesen; mit {model} liest der Nutzer jetzt ({research})",
|
|
726
737
|
"review.reread.done": "der Eintrag jeder Angabe blind mit {model} gelesen (strom read M… --blind): übereinstimmend → Notiz an der Angabe; abweichend → ein Widerspruch mit beiden Lesungen",
|
|
@@ -1155,6 +1166,10 @@
|
|
|
1155
1166
|
"ui.recent.more": "… und {n} weitere",
|
|
1156
1167
|
"ui.recent.morechanges": "(und weitere Änderungen: {n})",
|
|
1157
1168
|
"ui.history.none": "der Verlauf ist noch leer",
|
|
1169
|
+
"ui.history.past.hidden": "Ausgeblendet: {event} – {where}",
|
|
1170
|
+
"ui.history.past.shown": "Wieder angezeigt: {event} – {where}",
|
|
1171
|
+
"ui.history.past.same": "Unverändert: {event} – {where}",
|
|
1172
|
+
"ui.history.past.redo": "Die Ereignisse von {region} werden erneut gesucht (die gefundenen bleiben).",
|
|
1158
1173
|
"ui.browse.plan": "Was der Agent als Nächstes tut",
|
|
1159
1174
|
"ui.review.new": "{name} — {n, plural, one {# neue Aufgabe} other {# neue Aufgaben}}:",
|
|
1160
1175
|
"ui.review.nothing": "{name} — nichts Neues zu prüfen",
|
|
@@ -1704,6 +1719,7 @@
|
|
|
1704
1719
|
"ui.archives.agentbrowser.off": "Zurück zum Browser nur für Archive über den Browser?",
|
|
1705
1720
|
"ui.consent.remote": "Die Claude-Code-Sitzungen, die strom öffnet, mit Remote Control starten, damit sie sich auf claude.ai oder in der Claude-App auf dem Telefon verfolgen und steuern lassen?",
|
|
1706
1721
|
"ui.consent.addons": "Dem allein arbeitenden Agenten erlauben, die persönlichen Erweiterungen aus seinen Einstellungen zu laden (Skills, Plugins, MCP-Server – auch E-Mail oder Dokumente), wie im Chat? Er arbeitet dabei unbeaufsichtigt.",
|
|
1722
|
+
"ui.consent.history": "Die Ereignisse der Geschichte an den Orten aller Forschungen auf diesem Computer suchen – Kriege, Epidemien, Volkszählungen, Änderungen des Staates? Ein Experiment: der Agent sucht sie nur, wenn die Familienforschung nichts zu tun hat, und es kostet seine Zeit und die Nutzung des Abos.",
|
|
1707
1723
|
"ui.consent.effort": "Den Sitzungen von {agent}, die strom startet, den Denkaufwand {effort} geben? Ein höherer Denkaufwand (high, xhigh) verbraucht die Limits des Abonnements schneller.",
|
|
1708
1724
|
"ui.consent.webPerHost": "Dem eigenen Webabruf des Agenten bis zu {n, plural, one {# Anfrage} other {# Anfragen}} an eine Website (ihre Server und Spiegel zusammen) in einer Sitzung erlauben (jetzt {now})? Mehr Anfragen belasten die Website stärker; mehr Seiten einer Website gehen schonender über einen Connector.",
|
|
1709
1725
|
"ui.consent.effort.run": "{agent} für diesen Lauf mit dem Denkaufwand {effort} allein arbeiten lassen, höher als in der Einstellung ({now})? Ein höherer Denkaufwand (high, xhigh) verbraucht die Limits des Abonnements schneller.",
|
|
@@ -2654,6 +2670,17 @@
|
|
|
2654
2670
|
"ui.archives.permissions.title": "Die Archive der Downloader auf diesem Computer – was für ihre Bilder gilt:",
|
|
2655
2671
|
"ui.archives.state.way": "{way}, entschieden am {date}",
|
|
2656
2672
|
"ui.link.archive.none": "Über dieses Archiv gibt es hier nichts zu entscheiden. Es ist nichts geschehen.",
|
|
2673
|
+
"ui.experiments.link": "Die Suche nach den Ereignissen der Geschichte wird nur im Terminal eingeschaltet, das der Link öffnet.",
|
|
2674
|
+
"ui.link.what.experiment.history": "die Ereignisse der Geschichte an den Orten dieses Stammbaums suchen – Kriege, Epidemien, Volkszählungen, Änderungen des Staates",
|
|
2675
|
+
"ui.link.experiment.note": "Ein Experiment: gesucht wird nur, wenn die Familienforschung nichts zu tun hat, höchstens eine Sitzung am Tag bis {minutes} Minuten.",
|
|
2676
|
+
"ui.link.experiment.note.gate": "Ein Experiment: gesucht wird nur, wenn die Familienforschung nichts zu tun hat; wann, entscheidet das Tor der Läufe, eine Sitzung dauert höchstens {minutes} Minuten.",
|
|
2677
|
+
"ui.link.experiment.all": "Es wird in den Einstellungen dieses Computers eingeschaltet: für alle Forschungen darauf (jede lässt sich einzeln ausschalten).",
|
|
2678
|
+
"ui.link.experiment.on.done": "Die Suche nach den Ereignissen der Geschichte ist für diese Forschung eingeschaltet.",
|
|
2679
|
+
"ui.link.experiment.on.already": "Die Suche nach den Ereignissen der Geschichte ist für diese Forschung schon eingeschaltet. Es ist nichts geschehen.",
|
|
2680
|
+
"ui.link.experiment.off.done": "Die Suche nach den Ereignissen der Geschichte ist für diese Forschung ausgeschaltet; was gefunden wurde, bleibt.",
|
|
2681
|
+
"ui.link.experiment.off.already": "Die Suche nach den Ereignissen der Geschichte ist für diese Forschung schon ausgeschaltet. Es ist nichts geschehen.",
|
|
2682
|
+
"ui.link.experiment.archive": "Solange die Forschung als Archiv geführt wird, wird nach Ereignissen der Geschichte nicht gesucht. Es ist nichts geschehen.",
|
|
2683
|
+
"ui.link.experiment.waiting": "An dieser Forschung wird auf diesem Computer nicht gearbeitet, daher wird nach Ereignissen der Geschichte nicht gesucht. Es ist nichts geschehen.",
|
|
2657
2684
|
"ui.error.archive.permission": "das Herunterladen von Bildern aus dem Archiv {title} ({hosts}) wartet auf eine Entscheidung – seine Bedingungen schränken das automatische Herunterladen ein; beim Archiv wurde nichts angefragt",
|
|
2658
2685
|
"ui.error.archive.permission.new": "das Herunterladen von Bildern aus dem Archiv {title} ({hosts}) wartet auf eine Entscheidung – die Lesart der Bedingungen durch den Downloader hat noch niemand bestätigt; beim Archiv wurde nichts angefragt",
|
|
2659
2686
|
"ui.error.archive.permission.hint": "im Menü von strom entscheiden (Was wartet) oder im Terminal: strom allow archive {host} --way {ways}",
|
package/dist/brief/brief.js
CHANGED
|
@@ -31,6 +31,8 @@ import { hypothesisPeople } from "../core/directions.js";
|
|
|
31
31
|
import { imagesIndex, weakScans } from "../core/mediaindex.js";
|
|
32
32
|
import { SHARPER_SCAN } from "../core/views.js";
|
|
33
33
|
import { HYPOTHESIS_LINKS_ORIGIN, recordedLinks, recordedText } from "../core/hypolinks.js";
|
|
34
|
+
import { forHistory, historyOn } from "../core/pastevents.js";
|
|
35
|
+
import { HISTORY_WEB_RULE, historySections, localEventsSection } from "./history.js";
|
|
34
36
|
export { DEFAULT_BUDGET } from "../core/config.js";
|
|
35
37
|
import { DEFAULT_BUDGET, Settings } from "../core/config.js";
|
|
36
38
|
import { bookTuned, hostTuned, readingOf, treeTuning, tuningOn } from "../core/tune.js";
|
|
@@ -873,7 +875,7 @@ export function buildBrief(tree, opts) {
|
|
|
873
875
|
? `Working alone (strom run): nobody answers here, but the user may read this session afterwards (the run's output, its log) — every message of yours, the last one too, in ${langName(lang)}, about the work and never addressed to the user ("waits for a check", never "waits for you"); a step only the user can take goes into strom task wait.`
|
|
874
876
|
: "",
|
|
875
877
|
STROM_ONLY,
|
|
876
|
-
webRule(new Settings(tree.env, {}).webPerHost(tree.config)),
|
|
878
|
+
task && forHistory(task) ? HISTORY_WEB_RULE : webRule(new Settings(tree.env, {}).webPerHost(tree.config)),
|
|
877
879
|
opts.deadline !== undefined ? briefClock(opts.deadline) : "",
|
|
878
880
|
].filter(Boolean).join("\n"),
|
|
879
881
|
});
|
|
@@ -904,6 +906,10 @@ export function buildBrief(tree, opts) {
|
|
|
904
906
|
...filesCame(task),
|
|
905
907
|
].filter(Boolean).join("\n"),
|
|
906
908
|
});
|
|
909
|
+
// a task of history (the experiment): its own sections, nothing of the records, the method or the queue
|
|
910
|
+
const history = forHistory(task) ? historySections(tree, task, opts.shared, alone) : undefined;
|
|
911
|
+
if (history)
|
|
912
|
+
return assemble([...sections, ...history], budget);
|
|
907
913
|
// 2. a review: what each item of the task is, as the tree has it
|
|
908
914
|
if (task.origin.startsWith("review:") && task.where.length)
|
|
909
915
|
sections.push({ name: "review", required: true, pointer: `strom task show ${task.id}`, text: ["## To review", ...reviewItems(tree, task)].join("\n") });
|
|
@@ -1245,6 +1251,12 @@ export function buildBrief(tree, opts) {
|
|
|
1245
1251
|
// a task that links hypotheses reads no records: the parts of the method and the commands it uses, whatever its level
|
|
1246
1252
|
const kind = linking ? METHOD_LINKS : task?.level;
|
|
1247
1253
|
sections.push({ name: "method", first: true, pointer: "strom guide", text: methodFor(kind, conditions) });
|
|
1254
|
+
// 8'. the experiment of history on: a session that reads records may write a local event they tell of
|
|
1255
|
+
if (task && ["link", "verify", "intake", "enrich"].includes(kind ?? "") && historyOn(tree)) {
|
|
1256
|
+
const local = localEventsSection();
|
|
1257
|
+
if (local)
|
|
1258
|
+
sections.push(local);
|
|
1259
|
+
}
|
|
1248
1260
|
// 8 bis. the search beyond the registers: its budget of pages, printed pages for the user's model for print where the
|
|
1249
1261
|
// agent hands work to another model, and what the research has written of the person's places already
|
|
1250
1262
|
if (task?.origin === STORY_SOURCES_ORIGIN) {
|
|
@@ -1327,6 +1339,12 @@ export function buildBrief(tree, opts) {
|
|
|
1327
1339
|
"- a command you need: strom help <command> (short, with examples) — the full guide: strom guide",
|
|
1328
1340
|
].filter(Boolean).join("\n"),
|
|
1329
1341
|
});
|
|
1342
|
+
return assemble(sections, budget);
|
|
1343
|
+
}
|
|
1344
|
+
/**
|
|
1345
|
+
* The brief within its budget, from its sections in order.
|
|
1346
|
+
*/
|
|
1347
|
+
function assemble(sections, budget) {
|
|
1330
1348
|
// Assemble within the budget: required sections always, then the first ones whole when they fit, then the others in
|
|
1331
1349
|
// order — those in parts in short —, a first one that did not fit whole cut after them, and last the parts given in
|
|
1332
1350
|
// short made whole while they fit (UPGRADES); each written where it stands. Everything written counts: the blank line
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
// The brief of a session on the history of the places (the experiment experiments.history, core/pastevents.ts): a
|
|
2
|
+
// region's events looked for on the web, or the places of the facts mapped to regions — and, in a session that reads
|
|
3
|
+
// records, one line on the local events read in them. Only a brief of such a session speaks of it: the commands are
|
|
4
|
+
// behind the experiment's gate (hidden), the guide, help and strom commands say nothing of them.
|
|
5
|
+
import { langName } from "../core/lang.js";
|
|
6
|
+
import { foldText } from "../core/text.js";
|
|
7
|
+
import { match } from "../cli/registry.js";
|
|
8
|
+
import { synopsis } from "./sheet.js";
|
|
9
|
+
import { catalogIds, EVENT_KINDS, HISTORY_PLACES_ORIGIN, HOLD_DAYS, readCatalog, readHidden, readPlaces, regionName, regionOfTask, regionPeriod, REGION_LANGS, unmappedPlaces, } from "../core/pastevents.js";
|
|
10
|
+
import { factPlaces } from "../gedcom/export.js";
|
|
11
|
+
/** About so many events a region at most: rather fewer. */
|
|
12
|
+
export const REGION_DENSITY = 60;
|
|
13
|
+
/** So many events written already, listed in the brief (the rest: strom history status). */
|
|
14
|
+
const EVENTS_SHOWN = 120;
|
|
15
|
+
/** So many places waiting, listed. */
|
|
16
|
+
const PLACES_SHOWN = 80;
|
|
17
|
+
const TEXT_SHOWN = 90;
|
|
18
|
+
/** One command line from the registry (every option and its value), or nothing when it is not registered. */
|
|
19
|
+
function cmd(words) {
|
|
20
|
+
const m = match(words);
|
|
21
|
+
return m && m.used === words.length ? ` ${synopsis(m.def)}` : undefined;
|
|
22
|
+
}
|
|
23
|
+
function short(text, max = TEXT_SHOWN) {
|
|
24
|
+
const chars = [...text];
|
|
25
|
+
return chars.length > max ? `${chars.slice(0, max - 1).join("")}…` : text;
|
|
26
|
+
}
|
|
27
|
+
function years(from, to) {
|
|
28
|
+
return from === to ? String(from) : `${from}–${to}`;
|
|
29
|
+
}
|
|
30
|
+
/** The web's rule of the brief's head in a session of history (in place of brief.ts webRule: no connector here). */
|
|
31
|
+
export const HISTORY_WEB_RULE = "Search the web freely; read each page through strom history page <url> (below), never the web fetch tool — no connector and no task in this session.";
|
|
32
|
+
const NOTHING_ELSE = "Nothing of it goes into the tree's records or the GEDCOM: no person, fact, source or search is written in this session.";
|
|
33
|
+
const ONLY_FROM_PAGES = [
|
|
34
|
+
"- the source of each event: a page strom reads itself — strom history add downloads it, finds the quote on it (word for word, a part left out as …, the year in it) and refuses otherwise; strom checks every page, the person is asked nothing",
|
|
35
|
+
"- find pages with your own web search; read each page with strom history page <url> (--find \"<words>\": only the passages with them; --page <n>: its next part) and quote the words it prints — never the web fetch tool (WebFetch) for a page: it gives a model's summary, its words are not the page's, and the page would be read twice; strom history add checks the quote on the same read, one request a page",
|
|
36
|
+
"- a period: --from and --to as the page says them; the page says its end apart: a second --quote with that year (each ≤ 300 characters) — never a period shortened to fit one quote",
|
|
37
|
+
"- prefer encyclopedias, state institutions, archives and the Wikipedia in the region's language with its references; a page strom cannot read (refused, a bot check, a PDF, a page made by a script, one that sends to a consent or login page of another site): another source, or the event left out — never ask the person, never strom allow, never a browser for it",
|
|
38
|
+
"- this session writes events of history alone: no task (strom task add is refused here), no connector, nothing for the family research — many pages of one site go through strom history page, never a connector",
|
|
39
|
+
];
|
|
40
|
+
/**
|
|
41
|
+
* The sections of a session on a task of history, after its header and its task: what it is for, what was found
|
|
42
|
+
* already, the commands and how to finish. Undefined for any other task.
|
|
43
|
+
*/
|
|
44
|
+
export function historySections(tree, task, shared, alone) {
|
|
45
|
+
const region = regionOfTask(task);
|
|
46
|
+
if (region)
|
|
47
|
+
return regionSections(tree, region, shared, alone);
|
|
48
|
+
if (task.origin === HISTORY_PLACES_ORIGIN)
|
|
49
|
+
return placesSections(tree, shared, alone);
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
function closing(alone, lang, lines) {
|
|
53
|
+
return {
|
|
54
|
+
name: "closing",
|
|
55
|
+
required: true,
|
|
56
|
+
pointer: "",
|
|
57
|
+
text: [
|
|
58
|
+
"## Finishing",
|
|
59
|
+
...lines,
|
|
60
|
+
alone
|
|
61
|
+
? `- the summary: plain words for the record (the menu, the Strom app), in ${langName(lang)}, never addressed to the user, no advice; after strom session close you are done: a last message of one line at most`
|
|
62
|
+
: "- the user reads the summary (the menu, the Strom app): plain words, never addressed to them",
|
|
63
|
+
].join("\n"),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function regionSections(tree, region, shared, alone) {
|
|
67
|
+
const lang = tree.lang;
|
|
68
|
+
const c = shared ? readCatalog(shared, region) : undefined;
|
|
69
|
+
const name = regionName(c, lang, region);
|
|
70
|
+
const period = regionPeriod(tree, region);
|
|
71
|
+
const events = c?.events ?? [];
|
|
72
|
+
const live = events.filter((e) => !e.retracted);
|
|
73
|
+
// what the person hid in this tree: by event, and by kind (fewer of those kinds)
|
|
74
|
+
const hides = readHidden(tree);
|
|
75
|
+
const hiddenOf = new Map();
|
|
76
|
+
for (const h of hides)
|
|
77
|
+
hiddenOf.set(h.event, (hiddenOf.get(h.event) ?? 0) + 1);
|
|
78
|
+
const byKind = new Map();
|
|
79
|
+
for (const e of events)
|
|
80
|
+
if (hiddenOf.has(e.id))
|
|
81
|
+
byKind.set(e.kind, (byKind.get(e.kind) ?? 0) + hiddenOf.get(e.id));
|
|
82
|
+
const room = Math.max(0, REGION_DENSITY - live.length);
|
|
83
|
+
const out = [];
|
|
84
|
+
out.push({
|
|
85
|
+
name: "history",
|
|
86
|
+
required: true,
|
|
87
|
+
pointer: "strom history status",
|
|
88
|
+
text: [
|
|
89
|
+
`## The history of ${name} (${region}) — an experiment, for the Strom app`,
|
|
90
|
+
"What the ancestors lived through: the events of this region's history, shown in the Strom app with the lives of the people of its places. " + NOTHING_ELSE,
|
|
91
|
+
`- period: ${period.from}–${period.to} — this tree's places only (the oldest year of their facts in the region, never before 1600, to this year); another tree sharing the region adds its own years when it takes it`,
|
|
92
|
+
period.places.length
|
|
93
|
+
? `- this tree's places in it: ${period.places.map((p) => `${p.place}${p.from !== undefined || p.to !== undefined ? ` (${p.from ?? "…"}–${p.to ?? "…"})` : ""}${p.years.length ? ` facts ${years(Math.min(...p.years), Math.max(...p.years))}` : ""}`).join(" · ")}`
|
|
94
|
+
: "",
|
|
95
|
+
`- how many: at most about ${REGION_DENSITY} events for the region, rather fewer (${live.length} written${room ? `, room for about ${room} more` : ": enough — only what is missing badly"}) — those that shaped the lives of ordinary people there: wars and their levies, epidemics, famines, censuses, changes of the state and its borders, waves of emigration, laws on serfdom, land, schools, religion, great disasters; no lists of rulers, no battles far away, no happening of one village`,
|
|
96
|
+
`- kinds: ${EVENT_KINDS.join(", ")}`,
|
|
97
|
+
`- each event: its years (the day only when sure: --date); its texts in ${REGION_LANGS.join(", ")}, each ≤ 300 characters — factual and impersonal: what happened, where, how many; never addressed to anyone, never what to do, never speaking as yourself; --why-*: why it mattered for the people of the place; --tip-*: where a research may look because of it (a kind of record, an archive's series), impersonal too`,
|
|
98
|
+
"- a hard event (persecution, deportation, expulsion, famine, a pogrom): --sensitive; sober and factual, no judgement, no words of horror, and never a guess about the people of this tree — whom it touched is the reader's to see",
|
|
99
|
+
...ONLY_FROM_PAGES,
|
|
100
|
+
"- the same event again (one more source): --same-as <event>; the same kind and years yet another event: --distinct \"<why>\"; a better one in the place of one written: --replaces <event> (what the person hid holds on it); one that was wrong: strom history retract <event> --why \"…\"",
|
|
101
|
+
].filter(Boolean).join("\n"),
|
|
102
|
+
});
|
|
103
|
+
const kinds = [...byKind.entries()].sort((a, b) => b[1] - a[1]);
|
|
104
|
+
out.push({
|
|
105
|
+
name: "events",
|
|
106
|
+
first: true,
|
|
107
|
+
pointer: "strom history status --app --json",
|
|
108
|
+
text: [
|
|
109
|
+
`## Events of ${region} written already (${live.length}${events.length > live.length ? `, ${events.length - live.length} taken back` : ""}) — never one again; another source of one: --same-as`,
|
|
110
|
+
...(events.length
|
|
111
|
+
? events.slice(0, EVENTS_SHOWN).map((e) => {
|
|
112
|
+
const marks = [e.retracted ? `taken back: ${short(e.retracted.why || "–", 60)}${e.retracted.replacedBy ? ` → ${e.retracted.replacedBy}` : ""}` : "", hiddenOf.has(e.id) ? `hidden here ${hiddenOf.get(e.id)}×` : "", e.sensitive ? "sensitive" : ""].filter(Boolean);
|
|
113
|
+
return ` ${e.id} ${years(e.from, e.to)} ${e.kind} "${short(e.text[lang] ?? e.text.en ?? Object.values(e.text)[0] ?? "")}"${marks.length ? ` [${marks.join(" · ")}]` : ""}`;
|
|
114
|
+
})
|
|
115
|
+
: [" none yet"]),
|
|
116
|
+
events.length > EVENTS_SHOWN ? ` … ${events.length - EVENTS_SHOWN} more: strom history status --app --json` : "",
|
|
117
|
+
kinds.length ? `Hidden by the person in this tree, by kind: ${kinds.map(([k, n]) => `${k} ${n}`).join(" · ")} — fewer events of those kinds` : "Hidden by the person in this tree: none",
|
|
118
|
+
c?.tried.length ? `Pages strom could not read (never tried again): ${c.tried.slice(-20).map((t) => `${t.url} (${short(t.why, 40)})`).join(" · ")}` : "",
|
|
119
|
+
].filter(Boolean).join("\n"),
|
|
120
|
+
});
|
|
121
|
+
const commands = [cmd(["history", "page"]), cmd(["history", "add"]), cmd(["history", "retract"]), cmd(["history", "status"]), cmd(["history", "done"])].filter(Boolean);
|
|
122
|
+
if (commands.length)
|
|
123
|
+
out.push({ name: "commands", first: true, pointer: "strom help history add", text: ["## Commands (each option as it is)", ...commands].join("\n") });
|
|
124
|
+
out.push(closing(alone, lang, [
|
|
125
|
+
`- the events of the period found (or nothing more worth writing): strom history done ${region}, then strom session close --done "how many events, of which kinds, from which sources" --next "…"`,
|
|
126
|
+
`- time up before: strom session close --continue --summary "…" --next "the kinds or years not looked at yet" (the region stays this tree's for ${HOLD_DAYS} days)`,
|
|
127
|
+
`- nothing could be found or read at all: strom session close --continue --summary "what was tried" --next "…"`,
|
|
128
|
+
]));
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
131
|
+
function placesSections(tree, shared, alone) {
|
|
132
|
+
const lang = tree.lang;
|
|
133
|
+
const facts = factPlaces(tree);
|
|
134
|
+
const pending = unmappedPlaces(tree);
|
|
135
|
+
const records = tree.list("place").filter((p) => !p.retracted);
|
|
136
|
+
const byName = (key) => {
|
|
137
|
+
const f = foldText(key);
|
|
138
|
+
const first = foldText(key.split(",")[0].trim());
|
|
139
|
+
return records.find((p) => p.names.some((n) => foldText(n.name) === f)) ?? records.find((p) => p.names.some((n) => foldText(n.name) === first));
|
|
140
|
+
};
|
|
141
|
+
const placeLine = (key) => {
|
|
142
|
+
const ys = facts.get(key) ?? [];
|
|
143
|
+
const p = byName(key);
|
|
144
|
+
const parent = p?.parent ? tree.get(p.parent) : undefined;
|
|
145
|
+
const bits = [
|
|
146
|
+
ys.length ? `facts ${years(Math.min(...ys), Math.max(...ys))}` : "facts undated",
|
|
147
|
+
p ? `${p.id}${p.kind ? ` ${p.kind}` : ""}: ${p.names.map((n) => `${n.name}${n.lang ? ` (${n.lang})` : ""}${n.from || n.to ? ` ${n.from ?? "…"}–${n.to ?? "…"}` : ""}`).join(", ")}` : "",
|
|
148
|
+
parent ? `in ${parent.id} ${parent.names[0]?.name ?? ""}` : "",
|
|
149
|
+
p?.jurisdictions.length ? p.jurisdictions.map((j) => `${j.kind} ${j.name}`).join(", ") : "",
|
|
150
|
+
p?.coords ? `${p.coords.lat.toFixed(3)}, ${p.coords.lon.toFixed(3)}` : "",
|
|
151
|
+
].filter(Boolean);
|
|
152
|
+
return ` "${key}" — ${bits.join(" · ")}`;
|
|
153
|
+
};
|
|
154
|
+
const maps = readPlaces(tree);
|
|
155
|
+
const mapped = Object.keys(maps).length;
|
|
156
|
+
const regions = shared ? catalogIds(shared).map((id) => readCatalog(shared, id)).filter((c) => !!c) : [];
|
|
157
|
+
const out = [
|
|
158
|
+
{
|
|
159
|
+
name: "history",
|
|
160
|
+
required: true,
|
|
161
|
+
pointer: "strom history status",
|
|
162
|
+
text: [
|
|
163
|
+
"## The places of the facts on the map of history — an experiment, for the Strom app",
|
|
164
|
+
"Each place of the tree's facts gets the regions it belonged to, with the years: the historical land or province and the state whose history its people lived through (a land of a crown, then the state after it). The events are looked for later, region by region. " + NOTHING_ELSE,
|
|
165
|
+
"- a region's ID: a–z, 0–9 and hyphens, at most 24, the country's code first; a region that exists (below) is used again whenever it is the same unit; a new one gets its names in cs, en and de (strom history region)",
|
|
166
|
+
"- the years each place belonged to a region: --region <id>:<from>-<to> (an open end allowed); a place in two units at once (a land and its state): both",
|
|
167
|
+
"- a place that cannot be identified surely (several of that name, no parish or district to tell them apart): --unlocated --why \"…\" — a wrong region is worse than none",
|
|
168
|
+
"- other names of the place (another language, a historical name): --also",
|
|
169
|
+
"- what the tree knows of each place is below (the place records, their parents and jurisdictions); a reference work may be read on the web for it (strom history page <url>), nothing of it is written into the tree",
|
|
170
|
+
].join("\n"),
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: "places",
|
|
174
|
+
first: true,
|
|
175
|
+
pointer: "strom history status",
|
|
176
|
+
text: [
|
|
177
|
+
`## Places waiting (${pending.length}; ${mapped} mapped already)`,
|
|
178
|
+
...(pending.length ? pending.slice(0, PLACES_SHOWN).map(placeLine) : [" none: every place is mapped"]),
|
|
179
|
+
pending.length > PLACES_SHOWN ? ` … ${pending.length - PLACES_SHOWN} more: strom history status` : "",
|
|
180
|
+
].filter(Boolean).join("\n"),
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: "regions",
|
|
184
|
+
first: true,
|
|
185
|
+
pointer: "strom history status",
|
|
186
|
+
text: [
|
|
187
|
+
`## Regions that exist (${regions.length}) — the same unit: its ID again`,
|
|
188
|
+
...(regions.length
|
|
189
|
+
? regions.map((c) => ` ${c.region.id} — ${REGION_LANGS.map((l) => c.region.name[l]).filter(Boolean).join(" / ") || regionName(c, lang)}${c.done ? " (finished)" : ""}`)
|
|
190
|
+
: [" none yet"]),
|
|
191
|
+
].join("\n"),
|
|
192
|
+
},
|
|
193
|
+
];
|
|
194
|
+
const commands = [cmd(["history", "map"]), cmd(["history", "region"]), cmd(["history", "page"]), cmd(["history", "status"])].filter(Boolean);
|
|
195
|
+
if (commands.length)
|
|
196
|
+
out.push({ name: "commands", first: true, pointer: "strom help history map", text: ["## Commands (each option as it is)", ...commands].join("\n") });
|
|
197
|
+
out.push(closing(alone, lang, [
|
|
198
|
+
`- every place mapped or marked not located: strom session close --done "how many places, to which regions, how many not located" --next "…"`,
|
|
199
|
+
`- time up before: strom session close --continue --summary "…" --next "the places left"`,
|
|
200
|
+
]));
|
|
201
|
+
return out;
|
|
202
|
+
}
|
|
203
|
+
/** One short section for a session that reads records while the experiment is on: a local event read in them. */
|
|
204
|
+
export function localEventsSection() {
|
|
205
|
+
const line = cmd(["history", "local"]);
|
|
206
|
+
if (!line)
|
|
207
|
+
return undefined;
|
|
208
|
+
return {
|
|
209
|
+
name: "local events",
|
|
210
|
+
pointer: "strom help history local",
|
|
211
|
+
text: [
|
|
212
|
+
"## Local events (an experiment)",
|
|
213
|
+
"- an event of the place a source read in this session tells of (a fire, a flood, an epidemic, soldiers quartered — the priest's note in a register): written once, as the source says it, never guessed",
|
|
214
|
+
line,
|
|
215
|
+
].join("\n"),
|
|
216
|
+
};
|
|
217
|
+
}
|
package/dist/cli/menu-links.js
CHANGED
|
@@ -12,6 +12,7 @@ import { lines, truncate } from "./format.js";
|
|
|
12
12
|
import { isArchive } from "../core/mode.js";
|
|
13
13
|
import { actsAsArchive, kindOf } from "../core/state.js";
|
|
14
14
|
import { Tree } from "../core/tree.js";
|
|
15
|
+
import { DEFAULT_RUN_MINUTES } from "../core/config.js";
|
|
15
16
|
import { costPartial, monthSpend, sessionCost } from "../core/session.js";
|
|
16
17
|
import { adoptAskedSince, adoptFailedSince, adoptedAt, adoptionNeverCame, awaitAdoption, nothingSince, removedByItsDecision, SYNC_INBOX, undoSync, withoutImages } from "../core/sync.js";
|
|
17
18
|
import { moveToTrash } from "../core/trash.js";
|
|
@@ -180,6 +181,38 @@ export async function archiveAsked(ctx, run, lang, root, host) {
|
|
|
180
181
|
return stop(ctx, t("ui.link.archive.none"));
|
|
181
182
|
return decideArchive(ctx, run, lang, root, host, q, q?.archiveHosts);
|
|
182
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* An experiment of the research turned on or off from the Strom app (strom-research://experiment&name=history): on is
|
|
186
|
+
* asked once — what it does, how long, and that it is this computer's setting for every research on it when that
|
|
187
|
+
* changes — then this computer's setting on and the research's own off taken away; off is the research's at once.
|
|
188
|
+
*/
|
|
189
|
+
export async function experimentDo(ctx, run, lang, root, what) {
|
|
190
|
+
const t = translator(lang);
|
|
191
|
+
const tree = Tree.open(root, ctx.env);
|
|
192
|
+
const treeOff = tree.config.experimentsHistory === "off";
|
|
193
|
+
if (what === "off") {
|
|
194
|
+
if (treeOff)
|
|
195
|
+
return stop(ctx, t("ui.link.experiment.off.already"));
|
|
196
|
+
if ((await run(["config", "set", "experiments.history", "off", "--for-tree"], true)) !== 0)
|
|
197
|
+
return false;
|
|
198
|
+
out(ctx, t("ui.link.experiment.off.done"));
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
// this computer's setting (the user's config): on for every research here unless one turned it off
|
|
202
|
+
const userOn = ctx.settings.experimentsHistory(undefined);
|
|
203
|
+
if (userOn && !treeOff)
|
|
204
|
+
return stop(ctx, t("ui.link.experiment.on.already"));
|
|
205
|
+
const minutes = ctx.settings.number("run.minutes", tree.config, DEFAULT_RUN_MINUTES);
|
|
206
|
+
const note = lines(t(ctx.settings.runGate() ? "ui.link.experiment.note.gate" : "ui.link.experiment.note", { minutes }), userOn ? undefined : t("ui.link.experiment.all"));
|
|
207
|
+
if (!(await asks(ctx, lang, root, t("ui.link.what.experiment.history"), note, false)))
|
|
208
|
+
return false;
|
|
209
|
+
if (!userOn && (await run(["config", "set", "experiments.history", "on"], true)) !== 0)
|
|
210
|
+
return false;
|
|
211
|
+
if (treeOff && (await run(["config", "unset", "experiments.history", "--for-tree"], true)) !== 0)
|
|
212
|
+
return false;
|
|
213
|
+
out(ctx, t("ui.link.experiment.on.done"));
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
183
216
|
/** A direction of the research paused, ended (each with the person's reason, if they give one) or taken up again. */
|
|
184
217
|
export async function directionDo(ctx, run, lang, root, id, what) {
|
|
185
218
|
const t = translator(lang);
|
package/dist/cli/registry.js
CHANGED
|
@@ -49,8 +49,9 @@ export function register(...defs) {
|
|
|
49
49
|
registry.push(def);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
+
/** The commands help, strom commands, the guide and the brief show: every one but those behind a gate (hidden). */
|
|
52
53
|
export function commands() {
|
|
53
|
-
return registry;
|
|
54
|
+
return registry.filter((c) => !c.hidden);
|
|
54
55
|
}
|
|
55
56
|
export function optionsOf(def) {
|
|
56
57
|
// a command's own option of a global's name is its own (strom help --agent: the catalog, not an agent's name)
|
|
@@ -74,7 +75,7 @@ export function match(words) {
|
|
|
74
75
|
}
|
|
75
76
|
/** Command groups ("person") that have subcommands but no command of their own. */
|
|
76
77
|
export function subcommandsOf(prefix) {
|
|
77
|
-
return registry.filter((c) => c.path.length > prefix.length && prefix.every((w, i) => c.path[i] === w));
|
|
78
|
+
return registry.filter((c) => !c.hidden && c.path.length > prefix.length && prefix.every((w, i) => c.path[i] === w));
|
|
78
79
|
}
|
|
79
80
|
/** An alias's words that begin with these (a group of aliases only: "lesson" has "lesson show" among them). */
|
|
80
81
|
export function aliasExtends(prefix) {
|
package/dist/cli/ui.js
CHANGED
|
@@ -521,6 +521,7 @@ export const UI = {
|
|
|
521
521
|
"ui.run.stop.user": "by hand",
|
|
522
522
|
"ui.run.stop.time": "time limit",
|
|
523
523
|
"ui.run.stop.empty": "no open tasks",
|
|
524
|
+
"ui.run.stop.history": "the history of the places waits until tomorrow: one session a day without a gate (run.gate), nothing else to do",
|
|
524
525
|
"ui.run.stop.asleep": "nothing to do until {at} — the tasks left need {host}, which is not answering now",
|
|
525
526
|
"ui.run.stop.problems": "the evidence has problems — strom check",
|
|
526
527
|
"ui.run.stop.denied": "the agent was not allowed to run strom — its permissions or its sandbox kept it away; nothing more was started",
|
|
@@ -1135,6 +1136,10 @@ export const UI = {
|
|
|
1135
1136
|
"ui.recent.more": "… and {n} more",
|
|
1136
1137
|
"ui.recent.morechanges": "(and {n, plural, one {# more change} other {# more changes}})",
|
|
1137
1138
|
"ui.history.none": "nothing in the history yet",
|
|
1139
|
+
"ui.history.past.hidden": "Hidden: {event} at {where}",
|
|
1140
|
+
"ui.history.past.shown": "Shown again: {event} at {where}",
|
|
1141
|
+
"ui.history.past.same": "Nothing changed: {event} at {where}",
|
|
1142
|
+
"ui.history.past.redo": "The events of {region} will be looked for again (those found stay).",
|
|
1138
1143
|
"ui.browse.plan": "What the agent will do next",
|
|
1139
1144
|
"ui.review.new": "{name} — {n, plural, one {# new task} other {# new tasks}}:",
|
|
1140
1145
|
"ui.review.nothing": "{name} — nothing new to review",
|
|
@@ -1694,6 +1699,7 @@ export const UI = {
|
|
|
1694
1699
|
"ui.archives.agentbrowser.off": "Back to the browser only for archives through the browser?",
|
|
1695
1700
|
"ui.consent.remote": "Start the Claude Code sessions strom opens with Remote Control, so that they can be followed and steered from claude.ai or the Claude app on a phone?",
|
|
1696
1701
|
"ui.consent.addons": "Let the agent working alone load the personal add-ons of its own settings (skills, plugins, MCP servers — mail or documents among them), as in a conversation? It works with nobody watching.",
|
|
1702
|
+
"ui.consent.history": "Look for the events of history at the places of every research on this computer — wars, epidemics, censuses, changes of the state? An experiment: the agent looks for them only when the family research has nothing to do, and it takes its time and the plan's usage.",
|
|
1697
1703
|
"ui.consent.effort": "Let the {agent} sessions strom starts reason with the effort {effort}? A higher reasoning effort (high, xhigh) uses up the subscription's limits sooner.",
|
|
1698
1704
|
"ui.consent.webPerHost": "Let the agent's own web fetch make up to {n, plural, one {# request} other {# requests}} to one site (its servers and mirrors together) in a session (now {now})? More requests to one site put more load on it; more pages of one site go more gently through a connector.",
|
|
1699
1705
|
"ui.consent.effort.run": "Start {agent} working alone with the reasoning effort {effort} for this run, above the setting ({now})? A higher reasoning effort (high, xhigh) uses up the subscription's limits sooner.",
|
|
@@ -2515,6 +2521,17 @@ export const UI = {
|
|
|
2515
2521
|
"ui.archives.permissions.title": "The archives of the downloaders here \u2013 what holds for their images:",
|
|
2516
2522
|
"ui.archives.state.way": "{way}, decided {date}",
|
|
2517
2523
|
"ui.link.archive.none": "There is nothing to decide about this archive here. Nothing was done.",
|
|
2524
|
+
"ui.experiments.link": "The search for the events of history is turned on only in the terminal the link opens.",
|
|
2525
|
+
"ui.link.what.experiment.history": "look for the events of history at the places of this tree — wars, epidemics, censuses, changes of the state",
|
|
2526
|
+
"ui.link.experiment.note": "An experiment: looked for only when the family research has nothing to do, at most one session a day of up to {minutes} minutes.",
|
|
2527
|
+
"ui.link.experiment.note.gate": "An experiment: looked for only when the family research has nothing to do; when, the gate of the runs decides, a session of up to {minutes} minutes.",
|
|
2528
|
+
"ui.link.experiment.all": "It is turned on in this computer's settings: for every research on it (each can be turned off on its own).",
|
|
2529
|
+
"ui.link.experiment.on.done": "The search for the events of history is on for this research.",
|
|
2530
|
+
"ui.link.experiment.on.already": "The search for the events of history is on for this research already. Nothing was done.",
|
|
2531
|
+
"ui.link.experiment.off.done": "The search for the events of history is off for this research; what was found stays.",
|
|
2532
|
+
"ui.link.experiment.off.already": "The search for the events of history is off for this research already. Nothing was done.",
|
|
2533
|
+
"ui.link.experiment.archive": "Nothing of history is looked for while the research is kept as an archive. Nothing was done.",
|
|
2534
|
+
"ui.link.experiment.waiting": "Nobody works on this research on this computer, so nothing of history is looked for. Nothing was done.",
|
|
2518
2535
|
"ui.error.archive.permission": "downloading images from {title} ({hosts}) waits for a decision \u2013 its terms restrict automated downloading; nothing was asked of the archive",
|
|
2519
2536
|
"ui.error.archive.permission.new": "downloading images from {title} ({hosts}) waits for a decision \u2013 nobody has confirmed its downloader's reading of the terms yet; nothing was asked of the archive",
|
|
2520
2537
|
"ui.error.archive.permission.hint": "to be decided in strom's menu (What waits), or in a terminal: strom allow archive {host} --way {ways}",
|
package/dist/commands/checks.js
CHANGED
|
@@ -8,7 +8,7 @@ import { counted, lines, table } from "../cli/format.js";
|
|
|
8
8
|
import { check, SHARED_MISSING, sharedMissing } from "../core/check.js";
|
|
9
9
|
import { guard } from "../core/guard.js";
|
|
10
10
|
import { unprovenPeople } from "../core/review.js";
|
|
11
|
-
import { NOT_DOWNLOADED, notDownloaded, notDownloadedError, verifyFast, verifyFull } from "../core/integrity.js";
|
|
11
|
+
import { NOT_DOWNLOADED, SEALED_PATHS, notDownloaded, notDownloadedError, verifyFast, verifyFull } from "../core/integrity.js";
|
|
12
12
|
import { verifyCommitSeal } from "../core/seal.js";
|
|
13
13
|
import { adoptSeal } from "../cli/seal.js";
|
|
14
14
|
import { NeedsConsentError, StromError } from "../core/errors.js";
|
|
@@ -150,10 +150,10 @@ function repair(tree) {
|
|
|
150
150
|
const headSealed = head !== undefined && verifyCommitSeal(key, head.tree, head.message);
|
|
151
151
|
// Paths to compare: whatever differs between the sealed commit and the working tree.
|
|
152
152
|
const candidates = new Set();
|
|
153
|
-
for (const c of git.changes(tree.root,
|
|
153
|
+
for (const c of git.changes(tree.root, SEALED_PATHS))
|
|
154
154
|
candidates.add(c.path);
|
|
155
155
|
if (!headSealed) {
|
|
156
|
-
const r = git.runGit(tree.root, ["diff", "--name-only", "-z", sealed, "HEAD", "--",
|
|
156
|
+
const r = git.runGit(tree.root, ["diff", "--name-only", "-z", sealed, "HEAD", "--", ...SEALED_PATHS]);
|
|
157
157
|
for (const p of r.stdout.split("\0").filter(Boolean))
|
|
158
158
|
candidates.add(p);
|
|
159
159
|
}
|
|
@@ -178,7 +178,7 @@ function repair(tree) {
|
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
if (!headSealed)
|
|
181
|
-
tree.commit(`Repair: restore the sealed state of ${sealed.slice(0, 8)}\n\nCommits made outside strom were undone for data
|
|
181
|
+
tree.commit(`Repair: restore the sealed state of ${sealed.slice(0, 8)}\n\nCommits made outside strom were undone for data/, strom.json and history/.`, SEALED_PATHS);
|
|
182
182
|
return { restored, quarantined, from: sealed };
|
|
183
183
|
}
|
|
184
184
|
register({
|