strom-research 1.23.0-beta.1 → 1.23.0-beta.3

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 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.23.0
9
9
 
10
- *Připravuje se: bety do 1.23.0-beta.1. Oddíl bude úplný s vydáním.*
10
+ *Připravuje se: bety do 1.23.0-beta.3. Oddíl bude úplný s vydáním.*
11
11
 
12
12
  - **Osoba ukázaná zvoleným jménem.** Žena narozená pod jedním jménem, provdaná pod druhým a po rozvodu zase u prvního
13
13
  se dá ukazovat tímto jménem znovu, aniž by se přidávalo podruhé: `strom name primary <osoba> "<jméno>"` (a
@@ -16,6 +16,35 @@ Změny každé verze ve zkratce. Úplné poznámky a instalační řádky jsou n
16
16
  GEDCOM ho dá na první místo.
17
17
  - **Soubor pro aplikaci Strom bez varování.** Export pro aplikaci Strom varoval před nestandardní značkou u každé
18
18
  osoby se zvoleným jménem a u několika značek zdrojů; kontrola teď zná všechny vlastní značky Stromu.
19
+ - **Commit gitem navrch výzkumu zapečetěného dvěma klíči (Windows).** `strom check` radil zároveň `strom repair` i
20
+ „nikdy `strom repair`“ a `strom repair` vrátil zpět práci zapsanou klíčem terminálu. `strom repair` teď vrací jen
21
+ to, co se udělalo mimo strom, práce obou klíčů zůstává; potom klíče sjednotí `strom seal adopt` ve vlastním
22
+ terminálu – `strom check` říká oba kroky v tomto pořadí. Spuštěný z aplikace agenta balené pro Windows nechá `strom
23
+ repair` takový výzkum beze změny a odkáže na terminál; odmítnutý zápis tam odkáže na terminál také, už ne nejdřív
24
+ na `strom repair`. Po commitu gitem, který nezměnil žádný záznam, `strom repair` řekne, že výzkum znovu zapečetil,
25
+ už ne „nothing to repair“.
26
+ - **Pečetní klíč i tam, kde ho hledá starší strom (Windows).** Klíč převzatý z kopie aplikace balené pro Windows se
27
+ teď ukládá i do `%APPDATA%\strom\keys`, kde ho hledá strom 1.22.1 nebo starší v terminálu: po návratu ke starší verzi
28
+ zůstává výzkum na tomto počítači zapečetěný. Klíč, který tam už je, se nikdy nepřepíše.
29
+ - **Vyprávění páru schválené z aplikace Strom.** Dotaz v terminálu teď mluví o vyprávění páru, už ne o vyprávění
30
+ osoby.
31
+ - **`strom repair` jedním jazykem.** Každý jeho řádek („obnoveno“, „není co opravit“ …) je pro člověka v jazyce
32
+ výzkumu; agent je čte anglicky jako dřív.
33
+
34
+ ## 1.22.2
35
+
36
+ *30. 10. 2026 · patří k aplikaci Strom 3.17.1.*
37
+
38
+ - **Strom z desktopové aplikace agenta a z terminálu zase zapisují do jednoho výzkumu (Windows).** Desktopová aplikace
39
+ agenta může být pro Windows zabalená (MSIX) a každý soubor, který strom spuštěný z ní vytvořil v nastavení stromu, skončil
40
+ v soukromé kopii aplikace: strom z aplikace a strom z terminálu měly každý vlastní pečetní klíč a každý bral zápisy
41
+ druhého jako změnu mimo strom. Nastavení je teď mimo AppData (`%USERPROFILE%\.config\strom`) a samo se převezme ze
42
+ staré složky i z kopie aplikace (obě zůstanou, jak byly). Rozdvojený výzkum se opraví sám, kde to jde; jinak
43
+ klíče sjednotí `strom seal adopt` v terminálu (nabídka ho jednou nabídne) – každý záznam zkontrolovaný, nic se
44
+ neztratí, nikdy `strom repair`. `strom update` spuštěný z takové aplikace nic nenainstaluje (viděla by to jen ona)
45
+ a řekne, ať se spustí v terminálu; `strom doctor` najde kopii programu, kterou si aplikace drží pro sebe.
46
+ - **`strom repair` po commitu přes git, který nezměnil žádný záznam** (prázdný, jen poznámky), výzkum znovu zapečetí;
47
+ dřív commit zůstal nezapečetěný, každý zápis byl odmítnut a nebylo co opravit.
19
48
 
20
49
  ## 1.22.1
21
50
 
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.23.0
9
9
 
10
- *In Vorbereitung: die Betas bis 1.23.0-beta.1. Der Abschnitt ist mit dem Release vollständig.*
10
+ *In Vorbereitung: die Betas bis 1.23.0-beta.3. Der Abschnitt ist mit dem Release vollständig.*
11
11
 
12
12
  - **Eine Person unter dem gewählten Namen.** Eine Frau, unter einem Namen geboren, unter einem anderen verheiratet und
13
13
  nach einer Scheidung wieder beim ersten, lässt sich wieder unter diesem Namen zeigen, ohne dass er ein zweites Mal
@@ -18,6 +18,40 @@ Die Änderungen jeder Version in Kürze. Die vollständigen Hinweise und die Ins
18
18
  - **Die Datei für die Strom-App ohne Warnungen.** Der Export für die Strom-App warnte bei jeder Person mit gewähltem
19
19
  Namen und bei mehreren Kennzeichen von Quellen vor einem nicht standardisierten Tag; die Prüfung kennt jetzt alle
20
20
  eigenen Tags von Strom.
21
+ - **Ein Commit mit git über einer mit zwei Schlüsseln versiegelten Forschung (Windows).** `strom check` riet zugleich
22
+ zu `strom repair` und zu „nie `strom repair`“, und `strom repair` machte die mit dem Schlüssel des Terminals
23
+ geschriebene Arbeit rückgängig. `strom repair` macht jetzt nur rückgängig, was außerhalb von strom geschah, die
24
+ Arbeit beider Schlüssel bleibt; danach vereint `strom seal adopt` in einem eigenen Terminal die Schlüssel – `strom
25
+ check` nennt beide Schritte in dieser Reihenfolge. Aus der für Windows paketierten Desktop-App eines Agenten
26
+ gestartet, lässt `strom repair` eine solche Forschung unverändert und verweist auf das Terminal. Nach einem Commit
27
+ mit git, der keinen Eintrag änderte, sagt `strom repair`, dass es die Forschung neu versiegelt hat, nicht mehr
28
+ „nothing to repair“. Ein dort abgelehnter Schreibvorgang verweist ebenfalls auf das Terminal, nicht mehr zuerst auf
29
+ `strom repair`.
30
+ - **Der Siegelschlüssel auch dort, wo ein älteres strom sucht (Windows).** Ein aus der Kopie einer für Windows
31
+ paketierten App übernommener Schlüssel liegt jetzt auch in `%APPDATA%\strom\keys`, wo ihn strom 1.22.1 oder älter
32
+ im Terminal sucht: zurück bei einer älteren Version bleibt die Forschung auf diesem Computer versiegelt. Ein Schlüssel,
33
+ der dort schon liegt, wird nie ersetzt.
34
+ - **Die Erzählung eines Paares, aus der Strom-App freigegeben.** Die Frage im Terminal nennt jetzt die Erzählung des
35
+ Paares, nicht mehr die einer Person.
36
+ - **`strom repair` in einer Sprache.** Jede Zeile („wiederhergestellt“, „nichts zu reparieren“ …) steht für eine
37
+ Person in der Sprache der Forschung; ein Agent liest sie wie bisher auf Englisch.
38
+
39
+ ## 1.22.2
40
+
41
+ *30.10.2026 · gehört zur Strom-App 3.17.1.*
42
+
43
+ - **strom aus der Desktop-App eines Agenten und aus einem Terminal schreiben wieder in eine Forschung (Windows).** Die
44
+ Desktop-App eines Agenten kann für Windows verpackt sein (MSIX), und jede Datei, die ein von ihr gestartetes strom in den Einstellungen
45
+ von strom anlegte, landete in der privaten Kopie der App: das strom der App und das des Terminals hatten je einen
46
+ eigenen Siegelschlüssel, und jedes hielt die Schreibvorgänge des anderen für Änderungen außerhalb von strom. Die
47
+ Einstellungen liegen jetzt außerhalb von AppData (`%USERPROFILE%\.config\strom`) und werden aus dem alten Ordner
48
+ und aus der Kopie der App von selbst übernommen (beide bleiben, wie sie waren). Eine so geteilte Forschung heilt sich
49
+ selbst, wo es geht; sonst vereint `strom seal adopt` in einem Terminal die Schlüssel (das Menü bietet es einmal an) –
50
+ jeder Datensatz geprüft, nichts geht verloren, nie `strom repair`. Ein aus einer solchen App gestartetes
51
+ `strom update` installiert nichts (nur die App sähe es) und sagt, es im Terminal auszuführen; `strom doctor` findet
52
+ eine Kopie des Programms, die eine App für sich behält.
53
+ - **`strom repair` nach einem mit git gemachten Commit, der keinen Datensatz änderte** (leer, nur Notizen), versiegelt
54
+ die Forschung wieder; vorher blieb der Commit unversiegelt, jeder Schreibvorgang wurde abgelehnt, und es gab nichts zu reparieren.
21
55
 
22
56
  ## 1.22.1
23
57
 
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.23.0
9
9
 
10
- *In preparation: the betas up to 1.23.0-beta.1. The section is complete with the release.*
10
+ *In preparation: the betas up to 1.23.0-beta.3. The section is complete with the release.*
11
11
 
12
12
  - **A person shown by the name chosen.** A woman born under one name, married under another and back at the first
13
13
  after a divorce can be shown by that name again without it being added twice: `strom name primary <person>
@@ -16,6 +16,35 @@ The changes of each version in short. The full notes and the install lines are o
16
16
  name, the standard GEDCOM file gives it first.
17
17
  - **The file for the Strom app without warnings.** Exporting for the Strom app warned of a non-standard tag on each
18
18
  person with a chosen name and on several marks of sources; the check now knows every tag of Strom's own.
19
+ - **A commit made with git on top of a research sealed with two keys (Windows).** `strom check` advised `strom repair`
20
+ and never `strom repair` at once, and `strom repair` undid the work written with the terminal's key. `strom repair`
21
+ now undoes only what was done outside strom, the work of both keys stays; then `strom seal adopt` in a terminal
22
+ unites the keys — `strom check` says the two steps in this order. Started by an agent's desktop app packaged for
23
+ Windows, `strom repair` leaves such a research as it is and points to the terminal; a write refused there points to
24
+ the terminal too, no longer to `strom repair` first. After a commit made with git that changed no record, `strom
25
+ repair` says it sealed the research again, no longer "nothing to repair".
26
+ - **The seal key also where an older strom looks (Windows).** A key taken over from the copy of an app packaged for
27
+ Windows is now kept in `%APPDATA%\strom\keys` too, where a terminal's strom 1.22.1 or older looks for it: back on an
28
+ older version, the research is still sealed on this computer. A key there already is never replaced.
29
+ - **A couple's story approved from the Strom app.** The question in the terminal now names the story of the couple,
30
+ no longer of a person.
31
+ - **`strom repair` in one language.** Every line it writes ("restored", "nothing to repair", …) is in the research's
32
+ language for a person; an agent reads them in English as before.
33
+
34
+ ## 1.22.2
35
+
36
+ *2026-10-30 · goes with the Strom app 3.17.1.*
37
+
38
+ - **Strom from an agent's desktop app and from a terminal write to one research again (Windows).** An agent's
39
+ desktop app can be packaged for Windows (MSIX), and every file a strom it started made in strom's settings went to
40
+ the app's private copy: the app's strom and the terminal's each had a seal key of their own, and each refused the other's writes as
41
+ made outside strom. The settings are now outside AppData (`%USERPROFILE%\.config\strom`), taken over from the old
42
+ folder and from the app's copy by themselves (both left as they were). A research split so heals itself where it can;
43
+ else `strom seal adopt` in a terminal unites the keys (the menu offers it once) — every record checked, nothing lost,
44
+ never `strom repair`. `strom update` started from such an app installs nothing (only the app would see it) and says
45
+ to run it in a terminal; `strom doctor` finds a copy of the program an app keeps for itself.
46
+ - **`strom repair` after a commit made with git that changed no record** (an empty one, notes only) seals the research
47
+ again; before, the commit stayed unsealed, every write was refused and there was nothing to repair.
19
48
 
20
49
  ## 1.22.1
21
50
 
@@ -569,6 +569,8 @@
569
569
  "ui.tree.created": "✓ Rodokmen „{name}“ je založený: {dir}",
570
570
  "ui.chat.trust": "Claude Code se poprvé zeptá, jestli této složce důvěřovat. Je to složka rodokmenu, kterou vytvořil strom – stačí potvrdit „Yes, proceed“.",
571
571
  "ui.doc.program": "program",
572
+ "ui.doc.packaged": "kopie programu",
573
+ "ui.doc.packaged.copy": "aplikace zabalená pro Windows má vlastní kopii programu: {folders} – ta aplikace spouští jiný strom než terminál",
572
574
  "ui.doc.git": "git (historie)",
573
575
  "ui.doc.home": "složka výzkumu",
574
576
  "ui.doc.gitdir": "git ve složce výzkumů",
@@ -636,6 +638,7 @@
636
638
  "ui.doc.appurl.env.fix": "proměnnou STROM_APP_URL nastavit na adresu aplikace Strom ({web}, nebo její kopie na tomto počítači http://127.0.0.1:<port>/), nebo odebrat",
637
639
  "ui.doc.tree.ok": "{name}: data v pořádku a zapečetěná",
638
640
  "ui.doc.tree.bad": "{name}: {n, plural, one {# problém} few {# problémy} other {# problémů}}",
641
+ "ui.doc.tree.twokeys": "{name}: zapečetěno dvěma klíči stromu na tomto počítači (strom z aplikace a z terminálu) – zápisy obou jsou stromu",
639
642
  "ui.doc.write": "zápis do rodokmenu",
640
643
  "ui.doc.write.ok": "do jeho .strom i .git lze zapisovat",
641
644
  "ui.doc.write.sandbox": "{where}: zápis odepřen – strom běží pod agentem, nejspíš to zakazuje jeho sandbox",
@@ -672,6 +675,8 @@
672
675
  "ui.fix.git.inwindow": "Dokončit instalaci v okně systému a pak znovu spustit strom doctor.",
673
676
  "ui.fix.failed": "Nepovedlo se: {detail}",
674
677
  "ui.fix.app": "Otevřít aplikaci Strom v prohlížeči a nainstalovat ji?",
678
+ "ui.fix.packaged": "Přesunout kopii programu, kterou si aplikace drží pro sebe, do koše (aplikace pak spouští strom z terminálu)?",
679
+ "ui.fix.packaged.done": "V koši: {folder}",
675
680
  "ui.fix.nothing": "Nic, co by strom opravil sám – viz šipky.",
676
681
  "ui.why.git.human": "chybí git – strom v něm uchovává historii výzkumu",
677
682
  "ui.why.git.agent": "chybí git (strom v něm uchovává historii výzkumu): řekni to uživateli a spusť tohle – uživatel to potvrdí v okně systému",
@@ -1951,6 +1956,7 @@
1951
1956
  "ui.link.story.none": "Vyprávění o {person} zatím není. Nic se nestalo.",
1952
1957
  "ui.link.story.final": "Vyprávění o {person} už je schválené.",
1953
1958
  "ui.link.what.story": "schválit vyprávění osoby {person}, jak je (už nebude návrh).",
1959
+ "ui.link.what.story.couple": "schválit vyprávění páru {couple}, jak je (už nebude návrh).",
1954
1960
  "ui.link.story.done": "✓ Vyprávění je schválené. Po novém otevření výzkumu v aplikaci Strom tam bude bez štítku Návrh.",
1955
1961
  "ui.link.sync.none": "{input} není v tomto výzkumu poslání z aplikace Strom. Nic se nestalo.",
1956
1962
  "ui.link.sync.was": "Toto poslání už bylo vráceno.",
@@ -2246,8 +2252,8 @@
2246
2252
  "log.note.edit": "Opravená poznámka: {name}",
2247
2253
  "log.name.retract": "Odvolané jméno: {name} – {who}",
2248
2254
  "log.name.restore": "Vrácené jméno: {name} – {who}",
2249
- "log.name.primary": "Hlavní jméno: {name} – {who}",
2250
- "log.name.primary.clear": "Hlavní jméno zase rodné: {name} – {who}",
2255
+ "log.name.primary": "Za hlavní zvoleno jméno: {name} – {who}",
2256
+ "log.name.primary.clear": "Za hlavní zase rodné jméno: {name} – {who}",
2251
2257
  "log.note.retract": "Odvolaná poznámka: {name}",
2252
2258
  "log.note.restore": "Vrácená poznámka: {name}",
2253
2259
  "log.event.status": "Změněná jistota údaje: {who} – {fact}",
@@ -2573,6 +2579,8 @@
2573
2579
  "ui.error.folder.in-program.default.hint": "Zadat složku mimo ni: strom setup --home \"{suggested}\" --yes",
2574
2580
  "ui.error.update.in-program": "{folder} leží uvnitř {entry}, kterou aktualizace nahrazuje – výzkum by šel s ní. Nic se nenainstalovalo.",
2575
2581
  "ui.error.update.in-program.hint": "Nejdřív přesunout výzkum ze složky programu strom: strom setup ve vlastním terminálu (otázka na složku ho přesune i s výzkumem), pak znovu strom update",
2582
+ "ui.error.update.packaged": "Tento strom spustila aplikace zabalená pro Windows (MSIX): co by aktualizace nainstalovala do {folder}, uvidí jen ta aplikace, terminál by zůstal na {current}. Nic se nenainstalovalo.",
2583
+ "ui.error.update.packaged.hint": "strom update ve vlastním terminálu (PowerShell); aplikace novou verzi převezme odtud",
2576
2584
  "ui.error.tree.newer": "Tento rodokmen zapsal strom {by}, novější než tento strom {version}. Tento strom ho nechává beze změny.",
2577
2585
  "ui.error.tree.newer.hint": "Aktualizovat strom: strom update",
2578
2586
  "ui.error.tree.newer.backup": "Tento rodokmen zapsal strom {by}, novější než tento strom {version}. Tento strom ho nechává beze změny.",
@@ -3095,9 +3103,26 @@
3095
3103
  "ui.seal.ask": "Převzít „{name}“ na tomto počítači? Záznamy jsou zkontrolované a beze změn.",
3096
3104
  "ui.seal.adopted": "„{name}“ je teď zapečetěný na tomto počítači – zapisovat jde tady",
3097
3105
  "ui.seal.already": "„{name}“ je na tomto počítači zapečetěný už",
3106
+ "ui.seal.unite.ask": "„{name}“ je na tomto počítači zapečetěný dvěma klíči stromu (strom z aplikace a z terminálu, každý s vlastním nastavením). Sjednotit je? Záznamy jsou zkontrolované: nic se nezměnilo mimo strom, nic se neztratí.",
3107
+ "ui.seal.united": "„{name}“ je teď na tomto počítači zapečetěný jedním klíčem – zapisovat jde z aplikace i z terminálu",
3108
+ "ui.error.seal.other-key": "výzkum „{name}“ je na tomto počítači zapečetěný dvěma klíči stromu (strom z aplikace a z terminálu, každý s vlastním nastavením): nic se nezapsalo",
3109
+ "ui.error.seal.other-key.hint": "sjednotit ve vlastním terminálu: {set} – nikdy strom repair, ten by tu práci vrátil zpět",
3110
+ "ui.check.otherkey": "zapečetěno dvěma klíči stromu na tomto počítači (strom z aplikace a z terminálu): zápisy obou jsou stromu",
3111
+ "ui.check.otherkey.hint": "sjednotit ve vlastním terminálu: strom seal adopt – nikdy strom repair",
3098
3112
  "ui.seal.problems": "nepřevzato: záznamy nesedí se svou pečetí – co, řekne strom check",
3113
+ "ui.check.otherkey.afterrepair.hint": "po strom repair sjednotit ve vlastním terminálu: strom seal adopt",
3114
+ "ui.repair.resealed": "znovu zapečetěno – commit udělaný mimo strom nezměnil žádný záznam",
3115
+ "ui.repair.unite": "dál: sjednotit klíče stromu na tomto počítači ve vlastním terminálu: strom seal adopt",
3116
+ "ui.repair.nothing": "není co opravit – každý záznam odpovídá své pečeti",
3117
+ "ui.repair.restored": "obnoveno {file}",
3118
+ "ui.repair.removed": "odebráno {file}",
3119
+ "ui.repair.from": "zapečetěný stav: {commit} · kopie nahrazených souborů: .strom/quarantine/",
3120
+ "ui.repair.still": "{n, plural, one {zbývá # problém} few {zbývají # problémy} other {zbývá # problémů}} → strom verify",
3121
+ "ui.error.seal.repair-in-terminal": "výzkum „{name}“ obsahuje práci zapečetěnou klíčem stromu z terminálu, který strom spuštěný z aplikace nevidí: nic se neopravilo",
3122
+ "ui.error.seal.repair-in-terminal.hint": "ve vlastním terminálu: strom repair, pak strom seal adopt – ten vidí oba klíče a vrátí jen to, co se udělalo mimo strom",
3099
3123
  "ui.menu.seal": "Zapečetěno na jiném počítači: zapisovat tu jde až po převzetí (strom seal adopt).",
3100
3124
  "ui.seal.bridge": "výzkum „{name}“ je zapečetěný na jiném počítači: nic se nezapsalo – po převzetí na tomto počítači (terminál: strom seal adopt, nebo nabídka strom) poslat znovu",
3125
+ "ui.seal.bridge.twokeys": "výzkum „{name}“ je na tomto počítači zapečetěný dvěma klíči stromu (strom z aplikace a z terminálu): nic se nezapsalo – po sjednocení (terminál: strom seal adopt, nebo nabídka strom) poslat znovu",
3101
3126
  "ui.check.foreignseal": "zapečetěno na jiném počítači (nebo tu chybí nastavení stromu): číst jde, zapisovat až po převzetí tady",
3102
3127
  "ui.check.foreignseal.hint": "převzít ve vlastním terminálu: strom seal adopt – nebo v nabídce (strom)",
3103
3128
  "ui.why.seal.human": "výzkum je zapečetěný na jiném počítači: zapisovat tu jde až po převzetí (potvrzuje se v tomto terminálu)",
@@ -569,6 +569,8 @@
569
569
  "ui.tree.created": "✓ Der Stammbaum „{name}“ ist angelegt: {dir}",
570
570
  "ui.chat.trust": "Beim ersten Mal fragt Claude Code, ob diesem Ordner vertraut wird. Es ist der Ordner des Stammbaums, von strom angelegt – mit „Yes, proceed“ bestätigen.",
571
571
  "ui.doc.program": "Programm",
572
+ "ui.doc.packaged": "Kopie des Programms",
573
+ "ui.doc.packaged.copy": "eine für Windows verpackte App hat eine eigene Kopie des Programms: {folders} – diese App startet ein anderes strom als das Terminal",
572
574
  "ui.doc.git": "Git (Verlauf)",
573
575
  "ui.doc.home": "Forschungsordner",
574
576
  "ui.doc.gitdir": "git im Forschungsordner",
@@ -636,6 +638,7 @@
636
638
  "ui.doc.appurl.env.fix": "die Variable STROM_APP_URL auf eine Adresse der Strom-App setzen ({web}, oder eine Kopie auf diesem Computer http://127.0.0.1:<port>/) oder entfernen",
637
639
  "ui.doc.tree.ok": "{name}: Daten in Ordnung und versiegelt",
638
640
  "ui.doc.tree.bad": "{name}: {n, plural, one {# Problem} other {# Probleme}}",
641
+ "ui.doc.tree.twokeys": "{name}: mit zwei Schlüsseln von strom auf diesem Computer versiegelt (strom einer App und eines Terminals) – die Schreibvorgänge beider sind von strom",
639
642
  "ui.doc.write": "Schreiben in diesen Stammbaum",
640
643
  "ui.doc.write.ok": "in sein .strom und .git kann geschrieben werden",
641
644
  "ui.doc.write.sandbox": "{where}: Schreiben verweigert – strom läuft unter einem Agenten, wahrscheinlich verbietet es dessen Sandbox",
@@ -672,6 +675,8 @@
672
675
  "ui.fix.git.inwindow": "Die Installation im Fenster des Systems abschließen, dann strom doctor erneut starten.",
673
676
  "ui.fix.failed": "Das hat nicht geklappt: {detail}",
674
677
  "ui.fix.app": "Die Strom-App im Browser öffnen, um sie zu installieren?",
678
+ "ui.fix.packaged": "Die Kopie des Programms, die eine App für sich behält, in den Papierkorb legen (die App startet dann das strom des Terminals)?",
679
+ "ui.fix.packaged.done": "Im Papierkorb: {folder}",
675
680
  "ui.fix.nothing": "Nichts, was strom selbst beheben kann – siehe die Pfeile.",
676
681
  "ui.why.git.human": "Git fehlt – strom bewahrt darin den Verlauf der Forschung auf",
677
682
  "ui.why.git.agent": "Git fehlt (strom bewahrt darin den Verlauf auf): sag es dem Benutzer und führe dies aus – der Benutzer bestätigt in einem Fenster des Systems",
@@ -1951,6 +1956,7 @@
1951
1956
  "ui.link.story.none": "{person} hat noch keine Erzählung. Es ist nichts geschehen.",
1952
1957
  "ui.link.story.final": "Die Erzählung von {person} ist bereits freigegeben.",
1953
1958
  "ui.link.what.story": "die Erzählung von {person} so freigeben, wie sie ist (dann kein Entwurf mehr).",
1959
+ "ui.link.what.story.couple": "die Erzählung des Paares {couple} so freigeben, wie sie ist (dann kein Entwurf mehr).",
1954
1960
  "ui.link.story.done": "✓ Die Erzählung ist freigegeben. Wird die Forschung in der Strom-App erneut geöffnet, steht sie ohne das Etikett Entwurf da.",
1955
1961
  "ui.link.sync.none": "{input} ist in dieser Forschung keine Sendung aus der Strom-App. Es ist nichts geschehen.",
1956
1962
  "ui.link.sync.was": "Diese Sendung wurde bereits zurückgenommen.",
@@ -2573,6 +2579,8 @@
2573
2579
  "ui.error.folder.in-program.default.hint": "Einen Ordner außerhalb angeben: strom setup --home \"{suggested}\" --yes",
2574
2580
  "ui.error.update.in-program": "{folder} liegt in {entry}, das das Update ersetzt – die Forschung ginge mit. Nichts wurde installiert.",
2575
2581
  "ui.error.update.in-program.hint": "Zuerst die Forschung aus dem Programmordner von strom verschieben: strom setup in einem eigenen Terminal (die Frage nach dem Ordner verschiebt sie mit), dann erneut strom update",
2582
+ "ui.error.update.packaged": "Dieses strom wurde von einer für Windows verpackten App (MSIX) gestartet: was das Update in {folder} installierte, sähe nur diese App, das Terminal bliebe bei {current}. Nichts wurde installiert.",
2583
+ "ui.error.update.packaged.hint": "strom update in einem eigenen Terminal (PowerShell); die App übernimmt die neue Version von dort",
2576
2584
  "ui.error.tree.newer": "Diesen Stammbaum hat strom {by} geschrieben, neuer als dieses strom {version}. Dieses strom lässt ihn unverändert.",
2577
2585
  "ui.error.tree.newer.hint": "strom aktualisieren: strom update",
2578
2586
  "ui.error.tree.newer.backup": "Diesen Stammbaum hat strom {by} geschrieben, neuer als dieses strom {version}. Dieses strom lässt ihn unverändert.",
@@ -3095,9 +3103,26 @@
3095
3103
  "ui.seal.ask": "„{name}“ auf diesem Computer übernehmen? Die Einträge sind geprüft und unverändert.",
3096
3104
  "ui.seal.adopted": "„{name}“ ist jetzt auf diesem Computer versiegelt – schreiben geht hier",
3097
3105
  "ui.seal.already": "„{name}“ ist auf diesem Computer schon versiegelt",
3106
+ "ui.seal.unite.ask": "„{name}“ ist auf diesem Computer mit zwei Schlüsseln von strom versiegelt (strom aus einer App und aus einem Terminal, jedes mit eigenen Einstellungen). Vereinen? Alle Einträge sind geprüft: nichts außerhalb von strom geändert, nichts geht verloren.",
3107
+ "ui.seal.united": "„{name}“ ist jetzt auf diesem Computer mit einem Schlüssel versiegelt – schreiben geht aus der App wie aus dem Terminal",
3108
+ "ui.error.seal.other-key": "die Forschung „{name}“ ist auf diesem Computer mit zwei Schlüsseln von strom versiegelt (strom aus einer App und aus einem Terminal, jedes mit eigenen Einstellungen): nichts wurde geschrieben",
3109
+ "ui.error.seal.other-key.hint": "vereinen in einem eigenen Terminal: {set} – nie strom repair, das würde diese Arbeit rückgängig machen",
3110
+ "ui.check.otherkey": "mit zwei Schlüsseln von strom auf diesem Computer versiegelt (strom aus einer App und aus einem Terminal): was beide schrieben, ist von strom",
3111
+ "ui.check.otherkey.hint": "vereinen in einem eigenen Terminal: strom seal adopt – nie strom repair",
3098
3112
  "ui.seal.problems": "nicht übernommen: was im Stammbaum steht, ist nicht so versiegelt, wie strom es schrieb – was, sagt strom check",
3113
+ "ui.check.otherkey.afterrepair.hint": "nach strom repair vereinen in einem eigenen Terminal: strom seal adopt",
3114
+ "ui.repair.resealed": "neu versiegelt – der Commit außerhalb von strom änderte keinen Eintrag",
3115
+ "ui.repair.unite": "weiter: die Schlüssel von strom auf diesem Computer vereinen in einem eigenen Terminal: strom seal adopt",
3116
+ "ui.repair.nothing": "nichts zu reparieren – jeder Eintrag stimmt mit seiner Versiegelung überein",
3117
+ "ui.repair.restored": "wiederhergestellt {file}",
3118
+ "ui.repair.removed": "entfernt {file}",
3119
+ "ui.repair.from": "versiegelter Stand: {commit} · Kopien ersetzter Dateien: .strom/quarantine/",
3120
+ "ui.repair.still": "noch {n, plural, one {# Problem} other {# Probleme}} → strom verify",
3121
+ "ui.error.seal.repair-in-terminal": "die Forschung „{name}“ enthält Arbeit, versiegelt mit dem Schlüssel des strom aus dem Terminal, den ein aus einer App gestartetes strom nicht sieht: nichts wurde repariert",
3122
+ "ui.error.seal.repair-in-terminal.hint": "in einem eigenen Terminal: strom repair, dann strom seal adopt – es sieht beide Schlüssel und macht nur rückgängig, was außerhalb von strom geschah",
3099
3123
  "ui.menu.seal": "Auf einem anderen Computer versiegelt: schreiben hier erst nach der Übernahme (strom seal adopt).",
3100
3124
  "ui.seal.bridge": "die Forschung „{name}“ ist auf einem anderen Computer versiegelt: nichts wurde geschrieben – nach der Übernahme auf diesem Computer (Terminal: strom seal adopt, oder das Menü von strom) erneut senden",
3125
+ "ui.seal.bridge.twokeys": "die Forschung „{name}“ ist auf diesem Computer mit zwei Schlüsseln von strom versiegelt (strom einer App und eines Terminals): nichts wurde geschrieben – nach dem Vereinen (Terminal: strom seal adopt, oder das Menü von strom) erneut senden",
3101
3126
  "ui.check.foreignseal": "auf einem anderen Computer versiegelt (oder die Einstellungen von strom fehlen hier): lesen geht, schreiben erst nach der Übernahme hier",
3102
3127
  "ui.check.foreignseal.hint": "übernehmen in einem eigenen Terminal: strom seal adopt – oder im Menü (strom)",
3103
3128
  "ui.why.seal.human": "die Forschung ist auf einem anderen Computer versiegelt: schreiben hier erst nach der Übernahme (bestätigt in diesem Terminal)",
@@ -14,6 +14,7 @@ import { isArchive } from "../core/mode.js";
14
14
  import { Settings } from "../core/config.js";
15
15
  import { agentAppUrl, appSite } from "../core/stromapp.js";
16
16
  import { configDir, ownCommand } from "../core/paths.js";
17
+ import { oldSettingsDirs, packagedSettingsPattern } from "../core/oldsettings.js";
17
18
  import { within } from "../core/relocate.js";
18
19
  import { agentBrowser } from "../core/connector.js";
19
20
  import { CHROME_ALLOW, CHROME_DENY, chromeDomain } from "../core/browser.js";
@@ -212,6 +213,15 @@ export function settingsKeptFrom(dir, research, platform = process.platform) {
212
213
  return { path: p, folder };
213
214
  });
214
215
  }
216
+ /**
217
+ * What of strom's settings is kept from the agents: of today's folder, of each it was kept in before (oldsettings.ts),
218
+ * and every packaged app's copy whole, one made after these rules too.
219
+ */
220
+ function keptSettings(tree, settings) {
221
+ const research = researchFolders(tree, settings);
222
+ const packaged = packagedSettingsPattern(tree.env);
223
+ return [...[configDir(tree.env), ...oldSettingsDirs(tree.env)].flatMap((d) => settingsKeptFrom(d, research)), ...(packaged ? [{ path: packaged, folder: true }] : [])];
224
+ }
215
225
  /** The folders of the research the agent works in: its home, the shared folder, the tree. */
216
226
  function researchFolders(tree, settings) {
217
227
  return [settings.home()?.value, settings.shared()?.value, tree.root].filter((p) => !!p);
@@ -227,7 +237,7 @@ function treeRules(tree, agent) {
227
237
  const shared = settings.shared()?.value;
228
238
  const claude = agent === "claude";
229
239
  const at = (abs) => (claude ? permissionPath(abs) : abs.replace(/\\/g, "/"));
230
- const kept = settingsKeptFrom(configDir(tree.env), researchFolders(tree, settings)).map((k) => (k.folder ? `${at(k.path)}/**` : at(k.path)));
240
+ const kept = keptSettings(tree, settings).map((k) => (k.folder ? `${at(k.path)}/**` : at(k.path)));
231
241
  // Browser tools (Claude in Chrome): for the sites of the connectors fetching through the browser — or, agent.browser
232
242
  // always, of every archive of the research (anything else is asked in a conversation, not used in a run).
233
243
  const web = claude ? agentBrowser(tree, shared) : { on: false, hosts: [] };
@@ -402,7 +412,7 @@ export function opencodeConfig(tree) {
402
412
  }
403
413
  : {}),
404
414
  // the seal keys and the person's settings, and what the browser downloads (strom's to take over)
405
- ...Object.fromEntries(settingsKeptFrom(configDir(tree.env), researchFolders(tree, settings)).map((k) => [k.folder ? `${abs(k.path)}/*` : abs(k.path), "deny"])),
415
+ ...Object.fromEntries(keptSettings(tree, settings).map((k) => [k.folder ? `${abs(k.path)}/*` : abs(k.path), "deny"])),
406
416
  [`${abs(settings.downloads())}/*`]: "deny",
407
417
  },
408
418
  webfetch: "allow",
package/dist/cli/main.js CHANGED
@@ -13,6 +13,7 @@ import { commands, match } from "./registry.js";
13
13
  import { asCommand, asCommandJson, shellArg } from "./format.js";
14
14
  import { groupHelpAs, helpAs } from "./help.js";
15
15
  import { autoCommit } from "./commit.js";
16
+ import { takeOverOldSettings } from "../core/oldsettings.js";
16
17
  import { assertIntact } from "../core/integrity.js";
17
18
  import { head as gitHead, resetCache } from "../core/git.js";
18
19
  import { newerTree, Tree, VERSION } from "../core/tree.js";
@@ -226,6 +227,14 @@ async function mainOf(argv, io, env, cwd) {
226
227
  resetCache(undefined, "command");
227
228
  // the app's install line in its one variable (STROM_FROM): read as the five of an older line
228
229
  expandFromLine(env);
230
+ // strom's settings on Windows before (%APPDATA%\strom and a packaged app's copy of it) taken over, before anything
231
+ // reads them (core/oldsettings.ts)
232
+ try {
233
+ takeOverOldSettings(env);
234
+ }
235
+ catch {
236
+ // taken over next time; the old ones are read meanwhile
237
+ }
229
238
  // what ran and how long, for the reminder of the session's time
230
239
  const startedAt = Date.now();
231
240
  let ran;
@@ -442,7 +442,9 @@ export async function approveStory(ctx, run, lang, root, person, who, how = "fin
442
442
  if (st.status === "final")
443
443
  return stop(ctx, t("ui.link.story.final", { person: who }));
444
444
  out(ctx, lines(st.title ? `„${st.title}“` : undefined, "", st.text.replace(/\*\*/g, ""), ""));
445
- if (!(await asks(ctx, lang, root, t("ui.link.what.story", { person: who }))))
445
+ // a couple's story said as the couple's, never as a person's
446
+ const what = person.type === "family" ? t("ui.link.what.story.couple", { couple: who }) : t("ui.link.what.story", { person: who });
447
+ if (!(await asks(ctx, lang, root, what)))
446
448
  return false;
447
449
  if ((await run(["story", "approve", person.id], true)) !== 0)
448
450
  return false;
package/dist/cli/menu.js CHANGED
@@ -10,7 +10,7 @@ import fs from "node:fs";
10
10
  import path from "node:path";
11
11
  import { ui } from "./ui.js";
12
12
  import { isAgent } from "../core/which.js";
13
- import { offerAdopt } from "./seal.js";
13
+ import { offerAdopt, offerUnite } from "./seal.js";
14
14
  import { mb, setTidyAsked, tidyAskAgain, tidyAsked, tidyOn, tidyPlan, TIDY_SAID } from "../core/tidy.js";
15
15
  import { calibrationLabel, calibrationOffer } from "../core/viewsizes.js";
16
16
  /** A line as a sentence: its first letter capital (a catalog's text that also stands inside a line). */
@@ -231,6 +231,12 @@ export async function runMenu(ctx, run) {
231
231
  out();
232
232
  }
233
233
  }
234
+ else if (offerUnite(ctx, tree, !isAgent(ctx.env))) {
235
+ // sealed here with two keys of this computer (strom of an app packaged for Windows and of a terminal): united on
236
+ // the person's yes, offered once (as strom seal adopt: every operation and record checked)
237
+ await run(["seal", "adopt", "--tree", root]);
238
+ out();
239
+ }
234
240
  // what of it the Strom app does not show (only here in the terminal) said, so its number and the app's agree
235
241
  if (waiting)
236
242
  out(waitingLine(lang, waits));
package/dist/cli/seal.js CHANGED
@@ -1,8 +1,9 @@
1
1
  // Taking a family tree over on this computer (its seal): strom seal adopt, the menu and the setup go the same way —
2
2
  // every record checked against its seal, the person's yes, then this computer's key. Never by itself, never by an agent.
3
3
  import { ui } from "./ui.js";
4
- import { verifyFull } from "../core/integrity.js";
5
- import { createKey } from "../core/seal.js";
4
+ import { oneWay, verifyFull } from "../core/integrity.js";
5
+ import { settingsHidden } from "../core/oldsettings.js";
6
+ import { createKey, fingerprint, otherKeys } from "../core/seal.js";
6
7
  import { sealedHere } from "../core/tree.js";
7
8
  /**
8
9
  * The tree taken over here: refused while a record does not match its seal (what, strom check says), else asked — the
@@ -10,7 +11,7 @@ import { sealedHere } from "../core/tree.js";
10
11
  */
11
12
  export async function adoptSeal(ctx, tree, lang) {
12
13
  if (tree.key)
13
- return { adopted: false, why: "already" };
14
+ return uniteSeal(ctx, tree, lang);
14
15
  const problems = verifyFull(tree).findings.filter((f) => f.level === "error");
15
16
  if (problems.length)
16
17
  return { adopted: false, why: "problems", problems };
@@ -33,6 +34,16 @@ export function offerAdopt(ctx, root, person) {
33
34
  asked.add(root);
34
35
  return true;
35
36
  }
37
+ /**
38
+ * Whether to offer uniting this tree's keys now (strom update brought a strom that sees both): sealed here, another key
39
+ * of this computer that the check needs, a person at a terminal, not asked yet in this process.
40
+ */
41
+ export function offerUnite(ctx, tree, person) {
42
+ if (!person || !ctx.interactive || asked.has(tree.root) || !tree.key || !otherKeys(tree.env, tree.config.id, tree.key).length)
43
+ return false;
44
+ asked.add(tree.root);
45
+ return keysToUnite(tree).length > 0;
46
+ }
36
47
  /**
37
48
  * The family trees the setup found in the research's folder (strom brought back, a folder from another computer): each
38
49
  * said, and of one sealed on another computer how it is taken over — the setup then never ends with "strom init".
@@ -48,3 +59,37 @@ export function foundTrees(ctx, lang) {
48
59
  ];
49
60
  return { lines, foreign: foreign.map(({ name, root }) => ({ name, root })) };
50
61
  }
62
+ /**
63
+ * The other keys of this computer a tree sealed here needs united (strom of an app packaged for Windows and of a
64
+ * terminal each had their own: core/oldsettings.ts): none when the check finds nothing wrong, or none of them.
65
+ */
66
+ export function keysToUnite(tree) {
67
+ if (!tree.key)
68
+ return [];
69
+ if (!verifyFull(tree).findings.some((f) => f.level === "error"))
70
+ return [];
71
+ return otherKeys(tree.env, tree.config.id, tree.key).map((o) => o.key);
72
+ }
73
+ /**
74
+ * A tree sealed here with another key of this computer too: every operation of the other keys checked with them and
75
+ * every record against its seal — refused while anything does not match (a record changed outside strom stays refused),
76
+ * else the person's yes, then the operation seal.unite of this key (the other keys' operations until now taken) and its
77
+ * commit sealed with it.
78
+ */
79
+ async function uniteSeal(ctx, tree, lang) {
80
+ const others = keysToUnite(tree);
81
+ if (!others.length)
82
+ return { adopted: false, why: "already" };
83
+ // a change outside strom too: strom repair first (it keeps the work of both keys), then this again
84
+ const problems = oneWay(verifyFull(tree, { trust: others }).findings.filter((f) => f.level === "error"), () => settingsHidden(tree.env));
85
+ if (problems.length)
86
+ return { adopted: false, why: "problems", problems };
87
+ if (!(await ctx.confirm(ui(lang, "ui.seal.unite.ask", { name: tree.config.name }), true)))
88
+ return { adopted: false, why: "cancelled" };
89
+ const united = others.map(fingerprint);
90
+ tree.withTreeLock(() => {
91
+ tree.appendOp({ op: "seal.unite", targets: [], files: [], summary: "Seal keys of this computer united", keys: united });
92
+ tree.commit("Seal: keys of this computer united");
93
+ });
94
+ return { adopted: true, united };
95
+ }
package/dist/cli/ui.js CHANGED
@@ -540,6 +540,8 @@ export const UI = {
540
540
  "ui.tree.created": "✓ The family tree \"{name}\" is ready: {dir}",
541
541
  "ui.chat.trust": "The first time, Claude Code asks whether this folder is trusted. It is the family tree's folder, made by strom — confirm with \"Yes, proceed\".",
542
542
  "ui.doc.program": "program",
543
+ "ui.doc.packaged": "copy of the program",
544
+ "ui.doc.packaged.copy": "an app packaged for Windows keeps a copy of the program of its own: {folders} — that app runs another strom than the terminal",
543
545
  "ui.doc.git": "git (history)",
544
546
  "ui.doc.home": "research folder",
545
547
  "ui.doc.gitdir": "git in the research folder",
@@ -607,6 +609,7 @@ export const UI = {
607
609
  "ui.doc.appurl.env.fix": "the variable STROM_APP_URL set to an address of the Strom app ({web}, or a copy on this computer http://127.0.0.1:<port>/), or removed",
608
610
  "ui.doc.tree.ok": "{name}: data consistent and sealed",
609
611
  "ui.doc.tree.bad": "{name}: {n, plural, one {# problem} other {# problems}}",
612
+ "ui.doc.tree.twokeys": "{name}: sealed with two keys of strom on this computer (strom of an app and of a terminal) — writes of both are strom's",
610
613
  "ui.doc.write": "writing into this family tree",
611
614
  "ui.doc.write.ok": "its .strom and .git can be written",
612
615
  "ui.doc.write.sandbox": "{where}: writing refused — strom runs under an agent, most likely its sandbox forbids it",
@@ -643,6 +646,8 @@ export const UI = {
643
646
  "ui.fix.git.inwindow": "Finish the installation in the window of the system, then run strom doctor again.",
644
647
  "ui.fix.failed": "It did not work: {detail}",
645
648
  "ui.fix.app": "Open the Strom app in the browser, to install it?",
649
+ "ui.fix.packaged": "Put the copy of the program an app keeps for itself into the trash (the app then runs the strom of the terminal)?",
650
+ "ui.fix.packaged.done": "Into the trash: {folder}",
646
651
  "ui.fix.nothing": "Nothing strom can fix by itself — see the arrows.",
647
652
  "ui.why.git.human": "git is missing — strom keeps the history of the research in it",
648
653
  "ui.why.git.agent": "git is missing (strom keeps the research history in it): tell the user, then run this — the user says yes in a window of the system",
@@ -1925,6 +1930,7 @@ export const UI = {
1925
1930
  "ui.link.story.none": "{person} has no story yet. Nothing was done.",
1926
1931
  "ui.link.story.final": "The story of {person} is approved already.",
1927
1932
  "ui.link.what.story": "approve the story of {person} as it is (it will no longer be a draft).",
1933
+ "ui.link.what.story.couple": "approve the story of the couple {couple} as it is (it will no longer be a draft).",
1928
1934
  "ui.link.story.done": "✓ The story is approved. Open the research in the Strom app again and it is there without the draft label.",
1929
1935
  "ui.link.sync.none": "{input} is not a sending from the Strom app in this research. Nothing was done.",
1930
1936
  "ui.link.sync.was": "This sending was taken back already.",
@@ -2424,6 +2430,8 @@ export const UI = {
2424
2430
  "ui.error.folder.in-program.default.hint": "Name a folder outside it: strom setup --home \"{suggested}\" --yes",
2425
2431
  "ui.error.update.in-program": "{folder} lies inside {entry}, which the update replaces — the research would go with it. Nothing was installed.",
2426
2432
  "ui.error.update.in-program.hint": "First move the research out of strom's program folder: strom setup in a terminal of its own (the question about the folder moves it along), then strom update again",
2433
+ "ui.error.update.packaged": "This strom was started by an app packaged for Windows (MSIX): what the update installed into {folder} only that app would see, the terminal would stay at {current}. Nothing was installed.",
2434
+ "ui.error.update.packaged.hint": "strom update in a terminal of its own (PowerShell); the app takes the new version from there",
2427
2435
  "ui.error.tree.newer": "This family tree was written by strom {by}, newer than this strom {version}. This strom keeps it untouched.",
2428
2436
  "ui.error.tree.newer.hint": "Update strom: strom update",
2429
2437
  "ui.error.tree.newer.backup": "This family tree was written by strom {by}, newer than this strom {version}. This strom keeps it untouched.",
@@ -2787,9 +2795,26 @@ export const UI = {
2787
2795
  "ui.seal.ask": "Take over \"{name}\" on this computer? Its records were checked: unchanged.",
2788
2796
  "ui.seal.adopted": "\"{name}\" is sealed on this computer now — writing works here",
2789
2797
  "ui.seal.already": "\"{name}\" is sealed on this computer already",
2798
+ "ui.seal.unite.ask": "\"{name}\" was sealed with two keys of strom on this computer (strom of an app and of a terminal, each with settings of its own). Unite them? Every record was checked: nothing changed outside strom, nothing is lost.",
2799
+ "ui.seal.united": "\"{name}\" is sealed with one key on this computer now — writing works from the app and the terminal alike",
2800
+ "ui.error.seal.other-key": "\"{name}\" was sealed with two keys of strom on this computer (strom of an app and of a terminal, each with settings of its own): nothing written",
2801
+ "ui.error.seal.other-key.hint": "united in a terminal of its own: {set} — never strom repair, which would undo that work",
2802
+ "ui.check.otherkey": "sealed with two keys of strom on this computer (strom of an app and of a terminal): the writes of both are strom's own",
2803
+ "ui.check.otherkey.hint": "united in a terminal of its own: strom seal adopt — never strom repair",
2790
2804
  "ui.seal.problems": "not taken over: records do not match their seals — what, strom check says",
2805
+ "ui.check.otherkey.afterrepair.hint": "after strom repair, united in a terminal of its own: strom seal adopt",
2806
+ "ui.repair.resealed": "sealed again — the commit made outside strom changed no record",
2807
+ "ui.repair.unite": "next: the keys of strom on this computer united in a terminal of its own: strom seal adopt",
2808
+ "ui.repair.nothing": "nothing to repair — every record matches its seal",
2809
+ "ui.repair.restored": "restored {file}",
2810
+ "ui.repair.removed": "removed {file}",
2811
+ "ui.repair.from": "sealed state: {commit} · copies of replaced files: .strom/quarantine/",
2812
+ "ui.repair.still": "still {n, plural, one {# problem} other {# problems}} → strom verify",
2813
+ "ui.error.seal.repair-in-terminal": "\"{name}\" holds work sealed with the key of the terminal's strom, which a strom started by an app cannot see: nothing repaired",
2814
+ "ui.error.seal.repair-in-terminal.hint": "in a terminal of its own: strom repair, then strom seal adopt — it sees both keys and undoes only what was done outside strom",
2791
2815
  "ui.menu.seal": "Sealed on another computer: writing here only once taken over (strom seal adopt).",
2792
2816
  "ui.seal.bridge": "\"{name}\" was sealed on another computer: nothing was written — once it is taken over on this one (a terminal: strom seal adopt, or strom's menu), send again",
2817
+ "ui.seal.bridge.twokeys": "\"{name}\" was sealed with two keys of strom on this computer (strom of an app and of a terminal): nothing was written — once they are united (a terminal: strom seal adopt, or strom's menu), send again",
2793
2818
  "ui.check.foreignseal": "sealed on another computer (or strom's settings are not on this one): it can be read, written only once taken over here",
2794
2819
  "ui.check.foreignseal.hint": "taken over in a terminal of its own: strom seal adopt — or in strom's menu (strom)",
2795
2820
  "ui.why.seal.human": "the research was sealed on another computer: writing here only once taken over (confirmed in this terminal)",