strom-research 1.22.0-beta.3 → 1.22.0-beta.5
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 +7 -1
- package/CHANGELOG.de.md +8 -1
- package/CHANGELOG.md +9 -1
- package/assets/lang/cs.json +46 -0
- package/assets/lang/de.json +46 -0
- package/dist/brief/brief.js +19 -1
- package/dist/brief/history.js +234 -0
- package/dist/cli/menu-links.js +40 -0
- package/dist/cli/menu-settings.js +29 -0
- package/dist/cli/registry.js +3 -2
- package/dist/cli/ui.js +36 -0
- package/dist/cli/wizard.js +15 -2
- package/dist/commands/browse.js +49 -1
- package/dist/commands/checks.js +4 -4
- package/dist/commands/connectors.js +5 -0
- package/dist/commands/history.js +522 -0
- package/dist/commands/index.js +1 -0
- package/dist/commands/links.js +23 -0
- package/dist/commands/session.js +30 -5
- package/dist/commands/setup.js +87 -1
- package/dist/commands/tasks.js +11 -3
- package/dist/core/config.js +27 -0
- package/dist/core/integrity.js +70 -2
- package/dist/core/links.js +9 -2
- package/dist/core/live.js +210 -5
- package/dist/core/pack.js +23 -1
- package/dist/core/pagecheck.js +437 -0
- package/dist/core/pastevents.js +1347 -0
- package/dist/core/phrases.js +10 -0
- package/dist/core/queue.js +48 -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.5. 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,12 @@ 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
|
+
- **Co předek zažil.** Události v místech stromu – dějiny kraje ze stránek, které strom sám stáhl a ověřil, místní
|
|
30
|
+
události z přečtených záznamů – ukáže aplikace Strom; úvodní nastavení ho nabízí zapnuté, instalace nastavená dřív
|
|
31
|
+
zůstává, jak je, samo se nic nezapne. Zapnout ho může jen člověk; dokud je vypnuté, nic se nehledá. Po zapnutí se místa zmapují hned v dalším sezení a regiony se
|
|
32
|
+
prohledávají průběžně mezi sezeními rodinného výzkumu: zhruba každé 5. sezení (výchozí), každé 10., nebo jen když
|
|
33
|
+
není co jiného (`strom config set experiments.historyPace`, úvodní nastavení, Nastavení); kdy, řekne `strom plan`.
|
|
34
|
+
Nejdřív regiony s nejvíc osobami, země před státem nad ní.
|
|
29
35
|
|
|
30
36
|
## 1.21.0
|
|
31
37
|
|
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.5. 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,13 @@ 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
|
+
- **Was die Vorfahren erlebten.** Die Ereignisse an den Orten des Stammbaums – die Geschichte einer Region aus Seiten,
|
|
34
|
+
die strom selbst geladen und geprüft hat, örtliche Ereignisse aus gelesenen Einträgen – zeigt die Strom-App. Die
|
|
35
|
+
Ersteinrichtung schlägt es eingeschaltet vor; eine früher eingerichtete Installation bleibt, wie sie ist, nichts
|
|
36
|
+
schaltet sich von selbst ein. Einschalten kann es nur ein Mensch; solange es aus ist, wird nichts gesucht. Eingeschaltet, werden die Orte in der nächsten Sitzung zugeordnet und die Regionen ab und zu zwischen den
|
|
37
|
+
Sitzungen der Familienforschung durchsucht: etwa jede 5. Sitzung (Standard), jede 10. oder nur, wenn nichts anderes
|
|
38
|
+
ansteht (`strom config set experiments.historyPace`, die Ersteinrichtung, die Einstellungen); wann, sagt `strom plan`.
|
|
39
|
+
Zuerst die Regionen mit den meisten Personen, ein Land vor dem Staat darüber.
|
|
33
40
|
|
|
34
41
|
## 1.21.0
|
|
35
42
|
|
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.5. 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,14 @@ 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
|
+
- **What the ancestors lived through.** The events at the places of the tree — the history of a region from pages
|
|
32
|
+
strom downloaded and checked itself, local events from the records read — shown by the Strom app. The first setup
|
|
33
|
+
suggests it on; an installation set up before stays as it is, nothing turns on by itself. Only a person turns it
|
|
34
|
+
on; while it is off, nothing is looked for. Once on, the
|
|
35
|
+
places are mapped in the next session, and the regions are searched now and then between the family research's
|
|
36
|
+
sessions: about every 5th (the default), every 10th, or only when nothing else is left
|
|
37
|
+
(`strom config set experiments.historyPace`, the setup, the settings); `strom plan` says when. The regions
|
|
38
|
+
of the most people come first, a land before the state above it.
|
|
31
39
|
|
|
32
40
|
## 1.21.0
|
|
33
41
|
|
package/assets/lang/cs.json
CHANGED
|
@@ -721,6 +721,16 @@
|
|
|
721
721
|
"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
722
|
"archive.removed": "odebráno v aplikaci Strom",
|
|
723
723
|
"archive.wait": "Rozhodnutí o stahování z archivu {title}",
|
|
724
|
+
"history.why.archive": "Dokud je výzkum vedený jako archiv, nic se nehledá.",
|
|
725
|
+
"history.why.held": "Události regionu {region} hledá jiný výzkum na tomto počítači.",
|
|
726
|
+
"history.places.what": "Místa údajů pro dějiny předků ({n}): regiony, kam které patřilo, i s roky",
|
|
727
|
+
"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",
|
|
728
|
+
"history.places.done": "každé místo přiřazené k regionům i s roky, nebo označené jako nedohledané",
|
|
729
|
+
"history.region.what": "Události dějin v regionu {region}: války, epidemie, sčítání lidu, změny státu, vystěhovalectví",
|
|
730
|
+
"history.region.where": "encyklopedie, státní instituce, archivy, Wikipedie v jazyce regionu s jejími odkazy",
|
|
731
|
+
"history.region.why": "co předkové zažili, ukázané u jejich životů",
|
|
732
|
+
"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ý",
|
|
733
|
+
"history.region.finished": "události regionu {region} jsou hotové",
|
|
724
734
|
"review.reread.what": "Přečíst znovu modelem {model}, o co se opírají údaje osoby {name}: {list}{more}",
|
|
725
735
|
"review.reread.why": "tyto zápisy četl jen jiný model; {model} je ten, kterým uživatel čte teď ({research})",
|
|
726
736
|
"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 +1165,11 @@
|
|
|
1155
1165
|
"ui.recent.more": "… a další: {n}",
|
|
1156
1166
|
"ui.recent.morechanges": "(a další změny: {n})",
|
|
1157
1167
|
"ui.history.none": "historie je zatím prázdná",
|
|
1168
|
+
"ui.history.past.hidden": "Skryto: {event} – {where}",
|
|
1169
|
+
"ui.history.past.shown": "Znovu zobrazeno: {event} – {where}",
|
|
1170
|
+
"ui.history.past.same": "Beze změny: {event} – {where}",
|
|
1171
|
+
"ui.history.past.first": "Dějiny regionu {region} přijdou na řadu první z regionů, při nejbližším sezení dějin.",
|
|
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? Agent je hledá průběžně mezi sezeními rodinného výzkumu 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,36 @@
|
|
|
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": "Hledá se průběžně mezi sezeními rodinného výzkumu (jak často, se vybere hned potom), sezení trvá nejvýš {minutes} minut.",
|
|
2676
|
+
"ui.link.experiment.note.gate": "Hledá se průběžně mezi sezeními rodinného výzkumu (jak často, se vybere hned potom); zda sezení začne, rozhoduje brána běhů, sezení trvá nejvýš {minutes} minut.",
|
|
2677
|
+
"ui.history.pace.ask": "Jak často hledat události dějin, když agent pracuje sám?",
|
|
2678
|
+
"ui.history.pace.sometimes": "občas – zhruba každé 5. sezení",
|
|
2679
|
+
"ui.history.pace.rare": "zřídka – zhruba každé 10. sezení",
|
|
2680
|
+
"ui.history.pace.idle": "jen když rodinný výzkum nemá co dělat",
|
|
2681
|
+
"ui.history.pace.default": " (výchozí)",
|
|
2682
|
+
"ui.history.pace.later": "Jak často, jde později změnit: strom config set experiments.historyPace sometimes|rare|idle.",
|
|
2683
|
+
"ui.history.pace.off": "vypnuto – dějiny se nehledají",
|
|
2684
|
+
"ui.setup.history": "Hledat i události dějin v místech předků – války, epidemie, sčítání, změny státu (agent je hledá mezi sezeními rodinného výzkumu)? Jak často:",
|
|
2685
|
+
"ui.alone.history": "Dějiny míst: {state}",
|
|
2686
|
+
"ui.consent.history.pace": "Hledat události dějin častěji – {pace}? Stojí to víc času agenta i čerpání předplatného.",
|
|
2687
|
+
"ui.plan.history": "Dějiny míst: {what} – {when}.",
|
|
2688
|
+
"ui.plan.history.now": "v příštím sezení",
|
|
2689
|
+
"ui.plan.history.places": "příští sezení – nejdřív zmapovat místa",
|
|
2690
|
+
"ui.plan.history.in": "za ~{n} sezení",
|
|
2691
|
+
"ui.plan.history.idle": "až rodinný výzkum nebude mít co dělat",
|
|
2692
|
+
"ui.plan.history.asked": "; přednost: {region}, na přání",
|
|
2693
|
+
"ui.plan.history.order": "Regiony na řadě, po jednom: {list}",
|
|
2694
|
+
"ui.plan.history.weight": "{region} (osob: {n})",
|
|
2695
|
+
"ui.plan.history.prefer": "; přednost: místo {place} z nedávného sezení",
|
|
2696
|
+
"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ášť).",
|
|
2697
|
+
"ui.link.experiment.on.done": "Hledání událostí dějin je pro tento výzkum zapnuté.",
|
|
2698
|
+
"ui.link.experiment.on.already": "Hledání událostí dějin je pro tento výzkum zapnuté už. Nic se nestalo.",
|
|
2699
|
+
"ui.link.experiment.off.done": "Hledání událostí dějin je pro tento výzkum vypnuté; co už bylo nalezeno, zůstává.",
|
|
2700
|
+
"ui.link.experiment.off.already": "Hledání událostí dějin je pro tento výzkum vypnuté už. Nic se nestalo.",
|
|
2701
|
+
"ui.link.experiment.archive": "Dokud je výzkum vedený jako archiv, události dějin se nehledají. Nic se nestalo.",
|
|
2702
|
+
"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
2703
|
"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
2704
|
"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
2705
|
"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
|
@@ -721,6 +721,16 @@
|
|
|
721
721
|
"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
722
|
"archive.removed": "in der Strom-App entfernt",
|
|
723
723
|
"archive.wait": "Entscheidung über das Herunterladen aus dem Archiv {title}",
|
|
724
|
+
"history.why.archive": "Solange die Forschung als Archiv geführt wird, wird nichts gesucht.",
|
|
725
|
+
"history.why.held": "Die Ereignisse von {region} sucht eine andere Forschung auf diesem Computer.",
|
|
726
|
+
"history.places.what": "Die Orte der Angaben für die Geschichte der Vorfahren ({n}): zu welchen Regionen jeder gehörte, mit den Jahren",
|
|
727
|
+
"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",
|
|
728
|
+
"history.places.done": "jeder Ort seinen Regionen mit den Jahren zugeordnet oder als nicht auffindbar vermerkt",
|
|
729
|
+
"history.region.what": "Ereignisse der Geschichte in {region}: Kriege, Epidemien, Volkszählungen, Wechsel des Staates, Auswanderung",
|
|
730
|
+
"history.region.where": "Enzyklopädien, staatliche Institutionen, Archive, die Wikipedia in der Sprache der Region mit ihren Belegen",
|
|
731
|
+
"history.region.why": "was die Vorfahren erlebten, bei ihren Lebensläufen gezeigt",
|
|
732
|
+
"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",
|
|
733
|
+
"history.region.finished": "die Ereignisse von {region} sind fertig",
|
|
724
734
|
"review.reread.what": "Mit {model} neu lesen, worauf die Angaben von {name} beruhen: {list}{more}",
|
|
725
735
|
"review.reread.why": "diese Einträge hat nur ein anderes Modell gelesen; mit {model} liest der Nutzer jetzt ({research})",
|
|
726
736
|
"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 +1165,11 @@
|
|
|
1155
1165
|
"ui.recent.more": "… und {n} weitere",
|
|
1156
1166
|
"ui.recent.morechanges": "(und weitere Änderungen: {n})",
|
|
1157
1167
|
"ui.history.none": "der Verlauf ist noch leer",
|
|
1168
|
+
"ui.history.past.hidden": "Ausgeblendet: {event} – {where}",
|
|
1169
|
+
"ui.history.past.shown": "Wieder angezeigt: {event} – {where}",
|
|
1170
|
+
"ui.history.past.same": "Unverändert: {event} – {where}",
|
|
1171
|
+
"ui.history.past.first": "Die Geschichte von {region} kommt als erste der Regionen an die Reihe, bei der nächsten Sitzung der Geschichte.",
|
|
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? Der Agent sucht sie ab und zu zwischen den Sitzungen der Familienforschung, 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,36 @@
|
|
|
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": "Gesucht wird ab und zu zwischen den Sitzungen der Familienforschung (wie oft, wird gleich danach gewählt), eine Sitzung dauert höchstens {minutes} Minuten.",
|
|
2676
|
+
"ui.link.experiment.note.gate": "Gesucht wird ab und zu zwischen den Sitzungen der Familienforschung (wie oft, wird gleich danach gewählt); ob eine Sitzung beginnt, entscheidet das Tor der Läufe, eine Sitzung dauert höchstens {minutes} Minuten.",
|
|
2677
|
+
"ui.history.pace.ask": "Wie oft nach den Ereignissen der Geschichte suchen, wenn der Agent allein arbeitet?",
|
|
2678
|
+
"ui.history.pace.sometimes": "gelegentlich – etwa jede 5. Sitzung",
|
|
2679
|
+
"ui.history.pace.rare": "selten – etwa jede 10. Sitzung",
|
|
2680
|
+
"ui.history.pace.idle": "nur wenn die Familienforschung nichts zu tun hat",
|
|
2681
|
+
"ui.history.pace.default": " (Standard)",
|
|
2682
|
+
"ui.history.pace.later": "Wie oft, lässt sich später ändern: strom config set experiments.historyPace sometimes|rare|idle.",
|
|
2683
|
+
"ui.history.pace.off": "aus – keine Geschichte gesucht",
|
|
2684
|
+
"ui.setup.history": "Auch die Ereignisse der Geschichte an den Orten der Vorfahren suchen – Kriege, Epidemien, Volkszählungen, Änderungen des Staates (der Agent sucht sie zwischen den Sitzungen der Familienforschung)? Wie oft:",
|
|
2685
|
+
"ui.alone.history": "Geschichte der Orte: {state}",
|
|
2686
|
+
"ui.consent.history.pace": "Öfter nach den Ereignissen der Geschichte suchen – {pace}? Das kostet mehr Zeit des Agenten und mehr von der Nutzung des Abos.",
|
|
2687
|
+
"ui.plan.history": "Geschichte der Orte: {what} – {when}.",
|
|
2688
|
+
"ui.plan.history.now": "in der nächsten Sitzung",
|
|
2689
|
+
"ui.plan.history.places": "nächste Sitzung – zuerst die Orte zuordnen",
|
|
2690
|
+
"ui.plan.history.in": "in ~{n} Sitzungen",
|
|
2691
|
+
"ui.plan.history.idle": "wenn die Familienforschung nichts zu tun hat",
|
|
2692
|
+
"ui.plan.history.asked": "; zuerst: {region}, auf Bitte",
|
|
2693
|
+
"ui.plan.history.order": "Regionen der Reihe nach, eine nach der anderen: {list}",
|
|
2694
|
+
"ui.plan.history.weight": "{region} (Personen: {n})",
|
|
2695
|
+
"ui.plan.history.prefer": "; zuerst: der Ort {place} aus einer kürzlichen Sitzung",
|
|
2696
|
+
"ui.link.experiment.all": "Es wird in den Einstellungen dieses Computers eingeschaltet: für alle Forschungen darauf (jede lässt sich einzeln ausschalten).",
|
|
2697
|
+
"ui.link.experiment.on.done": "Die Suche nach den Ereignissen der Geschichte ist für diese Forschung eingeschaltet.",
|
|
2698
|
+
"ui.link.experiment.on.already": "Die Suche nach den Ereignissen der Geschichte ist für diese Forschung schon eingeschaltet. Es ist nichts geschehen.",
|
|
2699
|
+
"ui.link.experiment.off.done": "Die Suche nach den Ereignissen der Geschichte ist für diese Forschung ausgeschaltet; was gefunden wurde, bleibt.",
|
|
2700
|
+
"ui.link.experiment.off.already": "Die Suche nach den Ereignissen der Geschichte ist für diese Forschung schon ausgeschaltet. Es ist nichts geschehen.",
|
|
2701
|
+
"ui.link.experiment.archive": "Solange die Forschung als Archiv geführt wird, wird nach Ereignissen der Geschichte nicht gesucht. Es ist nichts geschehen.",
|
|
2702
|
+
"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
2703
|
"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
2704
|
"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
2705
|
"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,234 @@
|
|
|
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, coveredBy, 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}) — 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
|
+
// a state whose lands are done: their catalogs hold its events for these places and years — only what they lack
|
|
122
|
+
const cover = coveredBy(tree, shared, region);
|
|
123
|
+
if (cover.length) {
|
|
124
|
+
const theirs = cover.flatMap((id) => (shared ? (readCatalog(shared, id)?.events ?? []) : []).filter((e) => !e.retracted && e.to >= period.from).map((e) => ({ id, e })));
|
|
125
|
+
out.push({
|
|
126
|
+
name: "covered",
|
|
127
|
+
first: true,
|
|
128
|
+
pointer: "strom history status --app --json",
|
|
129
|
+
text: [
|
|
130
|
+
`## Found already for the same places and years: ${cover.join(", ")} (finished, ${theirs.length} events) — the Strom app shows them at these places`,
|
|
131
|
+
"- write only what they lack: an event of the whole state they do not have; one of them again is never written (not even with --same-as)",
|
|
132
|
+
`- they lack nothing worth writing: strom history done ${region} at once, no page read`,
|
|
133
|
+
...theirs.slice(0, EVENTS_SHOWN).map(({ e }) => ` ${e.id} ${years(e.from, e.to)} ${e.kind} "${short(e.text[lang] ?? e.text.en ?? Object.values(e.text)[0] ?? "")}"`),
|
|
134
|
+
theirs.length > EVENTS_SHOWN ? ` … ${theirs.length - EVENTS_SHOWN} more: strom history status --app --json` : "",
|
|
135
|
+
].filter(Boolean).join("\n"),
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
const commands = [cmd(["history", "page"]), cmd(["history", "add"]), cmd(["history", "retract"]), cmd(["history", "status"]), cmd(["history", "done"])].filter(Boolean);
|
|
139
|
+
if (commands.length)
|
|
140
|
+
out.push({ name: "commands", first: true, pointer: "strom help history add", text: ["## Commands (each option as it is)", ...commands].join("\n") });
|
|
141
|
+
out.push(closing(alone, lang, [
|
|
142
|
+
`- 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 "…"`,
|
|
143
|
+
`- 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)`,
|
|
144
|
+
`- nothing could be found or read at all: strom session close --continue --summary "what was tried" --next "…"`,
|
|
145
|
+
]));
|
|
146
|
+
return out;
|
|
147
|
+
}
|
|
148
|
+
function placesSections(tree, shared, alone) {
|
|
149
|
+
const lang = tree.lang;
|
|
150
|
+
const facts = factPlaces(tree);
|
|
151
|
+
const pending = unmappedPlaces(tree);
|
|
152
|
+
const records = tree.list("place").filter((p) => !p.retracted);
|
|
153
|
+
const byName = (key) => {
|
|
154
|
+
const f = foldText(key);
|
|
155
|
+
const first = foldText(key.split(",")[0].trim());
|
|
156
|
+
return records.find((p) => p.names.some((n) => foldText(n.name) === f)) ?? records.find((p) => p.names.some((n) => foldText(n.name) === first));
|
|
157
|
+
};
|
|
158
|
+
const placeLine = (key) => {
|
|
159
|
+
const ys = facts.get(key) ?? [];
|
|
160
|
+
const p = byName(key);
|
|
161
|
+
const parent = p?.parent ? tree.get(p.parent) : undefined;
|
|
162
|
+
const bits = [
|
|
163
|
+
ys.length ? `facts ${years(Math.min(...ys), Math.max(...ys))}` : "facts undated",
|
|
164
|
+
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(", ")}` : "",
|
|
165
|
+
parent ? `in ${parent.id} ${parent.names[0]?.name ?? ""}` : "",
|
|
166
|
+
p?.jurisdictions.length ? p.jurisdictions.map((j) => `${j.kind} ${j.name}`).join(", ") : "",
|
|
167
|
+
p?.coords ? `${p.coords.lat.toFixed(3)}, ${p.coords.lon.toFixed(3)}` : "",
|
|
168
|
+
].filter(Boolean);
|
|
169
|
+
return ` "${key}" — ${bits.join(" · ")}`;
|
|
170
|
+
};
|
|
171
|
+
const maps = readPlaces(tree);
|
|
172
|
+
const mapped = Object.keys(maps).length;
|
|
173
|
+
const regions = shared ? catalogIds(shared).map((id) => readCatalog(shared, id)).filter((c) => !!c) : [];
|
|
174
|
+
const out = [
|
|
175
|
+
{
|
|
176
|
+
name: "history",
|
|
177
|
+
required: true,
|
|
178
|
+
pointer: "strom history status",
|
|
179
|
+
text: [
|
|
180
|
+
"## The places of the facts on the map of history — for the Strom app",
|
|
181
|
+
"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,
|
|
182
|
+
"- 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)",
|
|
183
|
+
"- 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",
|
|
184
|
+
"- 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",
|
|
185
|
+
"- other names of the place (another language, a historical name): --also",
|
|
186
|
+
"- 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",
|
|
187
|
+
].join("\n"),
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: "places",
|
|
191
|
+
first: true,
|
|
192
|
+
pointer: "strom history status",
|
|
193
|
+
text: [
|
|
194
|
+
`## Places waiting (${pending.length}; ${mapped} mapped already)`,
|
|
195
|
+
...(pending.length ? pending.slice(0, PLACES_SHOWN).map(placeLine) : [" none: every place is mapped"]),
|
|
196
|
+
pending.length > PLACES_SHOWN ? ` … ${pending.length - PLACES_SHOWN} more: strom history status` : "",
|
|
197
|
+
].filter(Boolean).join("\n"),
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
name: "regions",
|
|
201
|
+
first: true,
|
|
202
|
+
pointer: "strom history status",
|
|
203
|
+
text: [
|
|
204
|
+
`## Regions that exist (${regions.length}) — the same unit: its ID again`,
|
|
205
|
+
...(regions.length
|
|
206
|
+
? regions.map((c) => ` ${c.region.id} — ${REGION_LANGS.map((l) => c.region.name[l]).filter(Boolean).join(" / ") || regionName(c, lang)}${c.done ? " (finished)" : ""}`)
|
|
207
|
+
: [" none yet"]),
|
|
208
|
+
].join("\n"),
|
|
209
|
+
},
|
|
210
|
+
];
|
|
211
|
+
const commands = [cmd(["history", "map"]), cmd(["history", "region"]), cmd(["history", "page"]), cmd(["history", "status"])].filter(Boolean);
|
|
212
|
+
if (commands.length)
|
|
213
|
+
out.push({ name: "commands", first: true, pointer: "strom help history map", text: ["## Commands (each option as it is)", ...commands].join("\n") });
|
|
214
|
+
out.push(closing(alone, lang, [
|
|
215
|
+
`- every place mapped or marked not located: strom session close --done "how many places, to which regions, how many not located" --next "…"`,
|
|
216
|
+
`- time up before: strom session close --continue --summary "…" --next "the places left"`,
|
|
217
|
+
]));
|
|
218
|
+
return out;
|
|
219
|
+
}
|
|
220
|
+
/** One short section for a session that reads records while the experiment is on: a local event read in them. */
|
|
221
|
+
export function localEventsSection() {
|
|
222
|
+
const line = cmd(["history", "local"]);
|
|
223
|
+
if (!line)
|
|
224
|
+
return undefined;
|
|
225
|
+
return {
|
|
226
|
+
name: "local events",
|
|
227
|
+
pointer: "strom help history local",
|
|
228
|
+
text: [
|
|
229
|
+
"## Local events",
|
|
230
|
+
"- 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",
|
|
231
|
+
line,
|
|
232
|
+
].join("\n"),
|
|
233
|
+
};
|
|
234
|
+
}
|
package/dist/cli/menu-links.js
CHANGED
|
@@ -12,6 +12,8 @@ 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";
|
|
16
|
+
import { choosePace } from "../commands/setup.js";
|
|
15
17
|
import { costPartial, monthSpend, sessionCost } from "../core/session.js";
|
|
16
18
|
import { adoptAskedSince, adoptFailedSince, adoptedAt, adoptionNeverCame, awaitAdoption, nothingSince, removedByItsDecision, SYNC_INBOX, undoSync, withoutImages } from "../core/sync.js";
|
|
17
19
|
import { moveToTrash } from "../core/trash.js";
|
|
@@ -180,6 +182,44 @@ export async function archiveAsked(ctx, run, lang, root, host) {
|
|
|
180
182
|
return stop(ctx, t("ui.link.archive.none"));
|
|
181
183
|
return decideArchive(ctx, run, lang, root, host, q, q?.archiveHosts);
|
|
182
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* An experiment of the research turned on or off from the Strom app (strom-research://experiment&name=history): on is
|
|
187
|
+
* asked once — what it does, how long, and that it is this computer's setting for every research on it when that
|
|
188
|
+
* changes — then this computer's setting on and the research's own off taken away; off is the research's at once.
|
|
189
|
+
*/
|
|
190
|
+
export async function experimentDo(ctx, run, lang, root, what) {
|
|
191
|
+
const t = translator(lang);
|
|
192
|
+
const tree = Tree.open(root, ctx.env);
|
|
193
|
+
const treeOff = tree.config.experimentsHistory === "off";
|
|
194
|
+
if (what === "off") {
|
|
195
|
+
if (treeOff)
|
|
196
|
+
return stop(ctx, t("ui.link.experiment.off.already"));
|
|
197
|
+
if ((await run(["config", "set", "experiments.history", "off", "--for-tree"], true)) !== 0)
|
|
198
|
+
return false;
|
|
199
|
+
out(ctx, t("ui.link.experiment.off.done"));
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
// this computer's setting (the user's config): on for every research here unless one turned it off
|
|
203
|
+
const userOn = ctx.settings.experimentsHistory(undefined);
|
|
204
|
+
if (userOn && !treeOff)
|
|
205
|
+
return stop(ctx, t("ui.link.experiment.on.already"));
|
|
206
|
+
const minutes = ctx.settings.number("run.minutes", tree.config, DEFAULT_RUN_MINUTES);
|
|
207
|
+
const note = lines(t(ctx.settings.runGate() ? "ui.link.experiment.note.gate" : "ui.link.experiment.note", { minutes }), userOn ? undefined : t("ui.link.experiment.all"));
|
|
208
|
+
if (!(await asks(ctx, lang, root, t("ui.link.what.experiment.history"), note, false)))
|
|
209
|
+
return false;
|
|
210
|
+
// how often, asked once it is on for this computer (the pace chosen before suggested): this computer's too
|
|
211
|
+
if (!userOn) {
|
|
212
|
+
const pace = (await choosePace(ctx, ctx.settings.historyPace(undefined))) ?? ctx.settings.historyPace(undefined);
|
|
213
|
+
if ((await run(["config", "set", "experiments.historyPace", pace], true)) !== 0)
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
if (!userOn && (await run(["config", "set", "experiments.history", "on"], true)) !== 0)
|
|
217
|
+
return false;
|
|
218
|
+
if (treeOff && (await run(["config", "unset", "experiments.history", "--for-tree"], true)) !== 0)
|
|
219
|
+
return false;
|
|
220
|
+
out(ctx, t("ui.link.experiment.on.done"));
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
183
223
|
/** A direction of the research paused, ended (each with the person's reason, if they give one) or taken up again. */
|
|
184
224
|
export async function directionDo(ctx, run, lang, root, id, what) {
|
|
185
225
|
const t = translator(lang);
|
|
@@ -11,6 +11,7 @@ import { Tree, VERSION } from "../core/tree.js";
|
|
|
11
11
|
import { replacedOnDisk } from "../core/self.js";
|
|
12
12
|
import { modelStep, shortcutName } from "./wizard.js";
|
|
13
13
|
import { DEFAULT_RUN_MINUTES } from "../core/config.js";
|
|
14
|
+
import { chooseHistory, historySuggested } from "../commands/setup.js";
|
|
14
15
|
import { askGate, ensureGatesDir, listGates, loadGate } from "../core/gate.js";
|
|
15
16
|
import { ensureHooksDir, hooksDir, listHooks } from "../core/hooks.js";
|
|
16
17
|
import { byHandOnly, listConnectors, routeOf, routesOf } from "../core/connector.js";
|
|
@@ -365,6 +366,18 @@ async function alone(ctx, run, lang, root) {
|
|
|
365
366
|
},
|
|
366
367
|
});
|
|
367
368
|
}
|
|
369
|
+
// the experiment of history: how often between the family research's sessions, or off — the person's choice here
|
|
370
|
+
// (before the test of a gate, which shows only with one set: the numbers never move)
|
|
371
|
+
const history = ctx.settings.experimentsHistory(undefined);
|
|
372
|
+
items.push({
|
|
373
|
+
key: "5",
|
|
374
|
+
label: t("ui.alone.history", { state: history ? t(`ui.history.pace.${ctx.settings.historyPace(undefined)}`) : t("ui.settings.off") }),
|
|
375
|
+
act: async () => {
|
|
376
|
+
const h = await chooseHistory(ctx, t("ui.setup.history"), historySuggested(ctx), { back: t("ui.browse.back") });
|
|
377
|
+
if (h)
|
|
378
|
+
await applyHistory(ctx, run, h);
|
|
379
|
+
},
|
|
380
|
+
});
|
|
368
381
|
if (set && shared)
|
|
369
382
|
items.push({
|
|
370
383
|
key: "3",
|
|
@@ -390,6 +403,22 @@ async function alone(ctx, run, lang, root) {
|
|
|
390
403
|
return { title: t("ui.alone.title"), items };
|
|
391
404
|
});
|
|
392
405
|
}
|
|
406
|
+
/**
|
|
407
|
+
* History on at the pace chosen, or off (the settings): through strom config set, as the person would type it — the
|
|
408
|
+
* pace first, so turning it on asks nothing more.
|
|
409
|
+
*/
|
|
410
|
+
async function applyHistory(ctx, run, choice) {
|
|
411
|
+
const on = ctx.settings.experimentsHistory(undefined);
|
|
412
|
+
if (choice === "off") {
|
|
413
|
+
if (on)
|
|
414
|
+
await run(["config", "set", "experiments.history", "off"], true);
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
if (choice !== ctx.settings.historyPace(undefined) || ctx.settings.config.experimentsHistoryPace === undefined)
|
|
418
|
+
await run(["config", "set", "experiments.historyPace", choice], true);
|
|
419
|
+
if (!on)
|
|
420
|
+
await run(["config", "set", "experiments.history", "on"], true);
|
|
421
|
+
}
|
|
393
422
|
/** The gate's name in "claude-usage 10". */
|
|
394
423
|
function loadGateName(spec) {
|
|
395
424
|
return spec.trim().split(/\s+/u)[0] ?? "";
|