strom-research 1.18.0-beta.9 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.cs.md +18 -12
- package/CHANGELOG.de.md +23 -14
- package/CHANGELOG.md +18 -10
- package/assets/lang/cs.json +11 -9
- package/assets/lang/de.json +9 -7
- package/dist/cli/ui.js +9 -7
- package/dist/commands/output.js +4 -2
- package/dist/commands/people.js +1 -0
- package/dist/commands/phone.js +2 -2
- package/dist/commands/read.js +5 -3
- package/dist/commands/readers.js +7 -1
- package/dist/commands/sync.js +1 -1
- package/dist/core/changelog.js +46 -5
- package/dist/core/damaged.js +251 -0
- package/dist/core/document.js +326 -41
- package/dist/core/excerpt.js +150 -15
- package/dist/core/live-read.js +3 -6
- package/dist/core/live.js +138 -8
- package/dist/core/readsync.js +9 -3
- package/dist/core/retractions.js +4 -1
- package/dist/core/stromapp.js +25 -3
- package/dist/core/sync.js +8 -1
- package/dist/core/tree.js +1 -1
- package/dist/gedcom/export.js +9 -2
- package/dist/gedcom/lines.js +63 -31
- package/dist/gedcom/validate.js +5 -1
- package/dist/runners/antigravity.js +35 -0
- package/dist/runners/codex.js +18 -6
- package/dist/runners/grok.js +9 -1
- package/dist/runners/opencode.js +43 -3
- package/package.json +1 -4
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.18.0
|
|
9
9
|
|
|
10
|
-
*
|
|
10
|
+
*21. 10. 2026 · patří k aplikaci Strom 3.14.0.*
|
|
11
11
|
|
|
12
12
|
- **Fotky z telefonu nastojato.** Fotka otočená podle údaje EXIF se čte tak, jak se má dívat, nastojato; místa na ní
|
|
13
13
|
vyznačená (výřezy, poloviny dvoustrany, uložená část) jsou místa obrázku, jak se ukazuje. Fotka sama zůstává, jak
|
|
@@ -16,14 +16,17 @@ Změny každé verze ve zkratce. Úplné poznámky a instalační řádky jsou n
|
|
|
16
16
|
na macOS, Windows i Linuxu — a originál zůstává, jak přišel. Fotka HEIC jde do aplikace Strom jako výřez JPEG.
|
|
17
17
|
Kde obrázek na počítači nic nepřevede, řekne to jedna věta i s tím, co by pomohlo; `strom tidy` převedené obrázky
|
|
18
18
|
po 30 dnech nebo nad 500 MB uklidí.
|
|
19
|
-
- **Jeden dokument přečtený naráz.** `strom document read` přečte fotku, sken nebo PDF jednoho dokumentu — zápis
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
- **Jeden dokument přečtený naráz.** `strom document read` přečte fotku, sken nebo PDF jednoho dokumentu — zápis z
|
|
20
|
+
matriky, dopis, listinu, náhrobek, rub fotky: přepis slovo od slova, překlad, význam starých slov a zkratek a osoby,
|
|
21
|
+
které jmenuje, i s tím, kdo ze stromu to může být. Nic se nedomýšlí: jméno, které v dokumentu není, vypadne — i
|
|
22
|
+
příjmení, nikdy se nebere od otce ani z jiné rodiny —, co nejde přečíst, je označené; druhý čtenář může číst naslepo.
|
|
23
|
+
Dokument na úředním formuláři, jako rodný list, si své osoby ponechá — dítě i oba rodiče s jejich podílem, i jméno a
|
|
24
|
+
příjmení psané proloženě a rodné příjmení po „roz.“ —, a dokument přečtený dřív je po aktualizaci ukáže, aniž by se
|
|
25
|
+
četl znovu. U každé osoby a události je i místo na stránce, kde stojí, takže aplikace Strom ukáže výřez každé z nich.
|
|
26
|
+
Do stromu se z toho nic nezapíše samo. Dokument už přečtený to o sobě řekne, takže se omylem nečte podruhé. Dokument
|
|
27
|
+
čtený znovu se ukazuje pod názvem svého souboru, nikdy pod kódem. Dokument poslaný z aplikace Strom najde agenta
|
|
28
|
+
stejně jako terminál — i nainstalovaného do vlastní složky, přes npm nebo Homebrew — místo hlášení, že agent není
|
|
29
|
+
nastavený. Čte ho každý agent, se kterým výzkum pracuje, s modelem a úsilím nastaveným pro výzkum.
|
|
27
30
|
- **Fotky z telefonu.** `strom phone on`, které zapíná jen člověk, pustí k počítači telefon v domácí síti (Wi-Fi
|
|
28
31
|
nebo kabel — nikdy mobilní síť ani VPN). Telefon se jednou spáruje přes QR kód; jeho stránka pak fotí nebo vybírá
|
|
29
32
|
z galerie a posílá fotky celé do stromu výzkumu, s poznámkou a osobou, kterou ukazují — stejně jako „Přidat
|
|
@@ -55,9 +58,12 @@ Změny každé verze ve zkratce. Úplné poznámky a instalační řádky jsou n
|
|
|
55
58
|
jde vrátit nulou. Most už nedrží složku rodokmenu, takže ji jde na Windows smazat, a sám skončí, když rodokmen zmizí
|
|
56
59
|
(rodokmen smaže `strom trees remove`). Konec stromu, kde křest neuvádí otce, je uzavřený, jakmile na něm nic neběží
|
|
57
60
|
– už nečeká natrvalo na rozhodnutí. Pramen přejmenovaný v aplikaci Strom se přejmenuje i ve výzkumu a signatura nebo
|
|
58
|
-
strana pramene přijde do aplikace k prameni samému („Signatura / strana“), i když ho zatím nic necituje.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
strana pramene přijde do aplikace k prameni samému („Signatura / strana“), i když ho zatím nic necituje. Emoji nebo
|
|
62
|
+
jiný vzácný znak, který soubor z aplikace Strom cestou poškodil (ukáže se jako ��), není přejmenování ani změna
|
|
63
|
+
poznámky: výzkum si nechá svůj text. Místo nebo jiný údaj delší než řádek souboru GEDCOM (255 bajtů) už nezastaví
|
|
64
|
+
jeho zápis a žádné emoji se nerozdělí tam, kde dlouhý řádek pokračuje. S `excerpts.for all` dostane v aplikaci Strom
|
|
65
|
+
výřez i pramen, který zatím nikdo necituje, pokud se vedle citovaných vejde do limitu – citované se kvůli němu
|
|
66
|
+
nezmenší; co se nevešlo, se řekne.
|
|
61
67
|
|
|
62
68
|
## 1.17.0
|
|
63
69
|
|
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.18.0
|
|
9
9
|
|
|
10
|
-
*
|
|
10
|
+
*21.10.2026 · gehört zur Strom-App 3.14.0.*
|
|
11
11
|
|
|
12
12
|
- **Handyfotos aufrecht.** Ein Foto, das nach seiner EXIF-Ausrichtung gedreht ist, wird gelesen, wie es gesehen
|
|
13
13
|
werden soll, aufrecht; die darauf markierten Stellen (Ausschnitte, die Hälften einer Doppelseite, ein gespeicherter
|
|
@@ -16,16 +16,21 @@ Die Änderungen jeder Version in Kürze. Die vollständigen Hinweise und die Ins
|
|
|
16
16
|
umgewandelt — unter macOS, Windows und Linux —, das Original bleibt, wie es kam. Ein HEIC-Foto geht als
|
|
17
17
|
JPEG-Ausschnitt in die Strom-App. Wo nichts auf dem Computer ein Bild umwandelt, sagt es ein Satz, auch was helfen
|
|
18
18
|
würde; `strom tidy` räumt umgewandelte Bilder nach 30 Tagen oder über 500 MB weg.
|
|
19
|
-
- **Ein Dokument auf einmal gelesen.** `strom document read` liest ein Foto, einen Scan oder eine PDF eines
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
- **Ein Dokument auf einmal gelesen.** `strom document read` liest ein Foto, einen Scan oder eine PDF eines Dokuments —
|
|
20
|
+
einen Matrikeleintrag, einen Brief, eine Urkunde, einen Grabstein, die Rückseite eines Fotos: die Abschrift Wort für
|
|
21
|
+
Wort, ihre Übersetzung, was alte Wörter und Abkürzungen bedeuten, und die genannten Personen, samt wem im Stammbaum
|
|
22
|
+
sie entsprechen können. Nichts wird ergänzt: ein Name, der nicht im Dokument steht, fällt weg — auch ein Nachname, nie
|
|
23
|
+
vom Vater oder aus einer anderen Familie genommen —, Unleserliches wird markiert; ein zweiter Leser kann blind lesen.
|
|
24
|
+
Ein Dokument auf einem amtlichen Formular, etwa eine Geburtsurkunde, behält seine Personen — das Kind und beide Eltern
|
|
25
|
+
mit ihrem Anteil, auch ein gesperrt getippter Name und ein Geburtsname nach „geb.“ —, und ein früher gelesenes
|
|
26
|
+
Dokument zeigt sie nach dem Update, ohne erneut gelesen zu werden. Jede Person und jedes Ereignis kommt mit der Stelle
|
|
27
|
+
auf der Seite, an der es steht, so zeigt die Strom-App von jedem
|
|
28
|
+
einen eigenen Ausschnitt.
|
|
29
|
+
In den Stammbaum gelangt nichts von selbst. Ein schon gelesenes Dokument sagt es, so wird es nicht versehentlich ein
|
|
30
|
+
zweites Mal gelesen. Ein erneut gelesenes Dokument wird unter dem Namen seiner Datei gezeigt, nie unter einem Code.
|
|
31
|
+
Ein aus der Strom-App gesendetes Dokument findet den Agenten wie das Terminal — auch einen in einem eigenen Ordner,
|
|
32
|
+
über npm oder Homebrew installierten —, statt zu melden, es sei kein Agent eingerichtet. Jeder Agent, mit dem die
|
|
33
|
+
Forschung arbeitet, liest es, mit dem Modell und dem Aufwand, die für die Forschung eingestellt sind.
|
|
29
34
|
- **Fotos vom Handy.** `strom phone on`, das nur ein Mensch einschaltet, lässt ein Handy im Heimnetz (WLAN oder
|
|
30
35
|
Kabel — nie ein Mobilfunknetz oder ein VPN) zu diesem Computer. Das Handy wird einmal per QR-Code gekoppelt; seine
|
|
31
36
|
Seite fotografiert dann oder wählt aus der Galerie und schickt die Fotos ganz in einen Stammbaum der Forschung, mit
|
|
@@ -64,9 +69,13 @@ Die Änderungen jeder Version in Kürze. Die vollständigen Hinweise und die Ins
|
|
|
64
69
|
Stammbaum weg ist (einen Stammbaum löscht `strom trees remove`). Ein Ende des Baums, wo die Taufe keinen Vater
|
|
65
70
|
nennt, ist ein geschlossenes Ende, sobald nichts mehr daran läuft – es wartet nicht mehr für immer auf eine
|
|
66
71
|
Entscheidung. Eine in der Strom-App umbenannte Quelle heißt auch in der Forschung neu, und Signatur oder Seite einer
|
|
67
|
-
Quelle kommen in der App bei der Quelle selbst an, auch bevor etwas sie zitiert.
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
Quelle kommen in der App bei der Quelle selbst an, auch bevor etwas sie zitiert. Ein Emoji oder ein anderes seltenes
|
|
73
|
+
Zeichen, das die Datei der Strom-App unterwegs beschädigt hat (als �� zu sehen), ist keine Umbenennung und keine
|
|
74
|
+
geänderte Notiz: Die Forschung behält ihren Text. Ein Ort oder ein anderer Wert, länger als eine Zeile der
|
|
75
|
+
GEDCOM-Datei (255 Bytes), hält das Schreiben der Datei nicht mehr auf, und kein Emoji wird dort geteilt, wo eine
|
|
76
|
+
lange Zeile weitergeht. Mit `excerpts.for all` bekommt auch eine Quelle, die noch niemand zitiert, in der Strom-App
|
|
77
|
+
ihren Ausschnitt, soweit er neben den zitierten unter die Grenze passt – die zitierten werden dafür nie kleiner; was
|
|
78
|
+
nicht passte, wird gesagt.
|
|
70
79
|
|
|
71
80
|
## 1.17.0
|
|
72
81
|
|
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.18.0
|
|
9
9
|
|
|
10
|
-
*
|
|
10
|
+
*2026-10-21 · goes with the Strom app 3.14.0.*
|
|
11
11
|
|
|
12
12
|
- **Phone photos upright.** A photo turned by its EXIF orientation is read as it is meant to be seen, upright; the
|
|
13
13
|
places marked on it (excerpts, the halves of a spread, a cut-out part) are of the picture as it is shown. The
|
|
@@ -18,12 +18,17 @@ The changes of each version in short. The full notes and the install lines are o
|
|
|
18
18
|
help; `strom tidy` clears the converted pictures away after 30 days or above 500 MB.
|
|
19
19
|
- **One document read at once.** `strom document read` reads a photo, a scan or a PDF of one document — a register
|
|
20
20
|
entry, a letter, a deed, a gravestone, the back of a photo: the transcript word for word, its translation, what its
|
|
21
|
-
old words and abbreviations mean, and the people it names, with who of the tree they may be. Nothing is filled in:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
document
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
old words and abbreviations mean, and the people it names, with who of the tree they may be. Nothing is filled in: a
|
|
22
|
+
name the document does not have is left out — a surname too, never taken from a father or another family —, what
|
|
23
|
+
cannot be read is marked; a second reader can read it blind. A
|
|
24
|
+
document on a printed form, as a birth certificate, keeps its people — the child and both parents with their part in
|
|
25
|
+
it, their names typed letter-spaced and a mother's birth name after "née" or "roz." too —, and a document read before
|
|
26
|
+
shows them after the update with nothing read again. Each person and event it names comes with the place on the page
|
|
27
|
+
where it stands, so the Strom app shows each its own excerpt. Nothing of it enters the tree by itself. A document read
|
|
28
|
+
already says so, so it is not read a second time by mistake. A document read again is shown under the name of its
|
|
29
|
+
file, never a code. A document sent from the Strom app finds the agent as the terminal does — one installed in a
|
|
30
|
+
folder of its own, by npm or Homebrew too — instead of saying no agent is set up. Every agent the research works with
|
|
31
|
+
reads it, with the model and effort set for the research.
|
|
27
32
|
- **Photos from a phone.** `strom phone on`, turned on by the person alone, lets a phone on the home network (Wi-Fi
|
|
28
33
|
or a cable — never a mobile network or a VPN) reach this computer. The phone is paired once by its QR code; its
|
|
29
34
|
page then takes photos or picks them from the gallery and sends them whole into a tree of the research, with a
|
|
@@ -59,9 +64,12 @@ The changes of each version in short. The full notes and the install lines are o
|
|
|
59
64
|
Windows can delete it, and ends by itself once the tree is gone (`strom trees remove` deletes a tree). An end of the
|
|
60
65
|
tree where the baptism names no father is a closed end once nothing runs on it, no longer waiting for a decision for
|
|
61
66
|
good. A source renamed in the Strom app is renamed in the research too, and a source's call number or page reaches
|
|
62
|
-
the app on the source itself, also before anything cites it.
|
|
63
|
-
its
|
|
64
|
-
|
|
67
|
+
the app on the source itself, also before anything cites it. An emoji or another rare sign the Strom app's file
|
|
68
|
+
damaged on its way (shown as ��) is no rename and no changed note: the research keeps its text. A place or another
|
|
69
|
+
value longer than a line of the GEDCOM file (255 bytes) no longer stops the file from being written, and no emoji is
|
|
70
|
+
split where a long line goes on. With `excerpts.for all` a source nobody cites yet gets its excerpt in the Strom app
|
|
71
|
+
too, wherever it fits under the limit beside the cited ones, which never get smaller for it; what did not fit is
|
|
72
|
+
said.
|
|
65
73
|
|
|
66
74
|
## 1.17.0
|
|
67
75
|
|
package/assets/lang/cs.json
CHANGED
|
@@ -925,7 +925,7 @@
|
|
|
925
925
|
"ui.show.age": "věk {age}",
|
|
926
926
|
"ui.show.ages": "věk {ages}",
|
|
927
927
|
"ui.show.with": "uvedeni: {who}",
|
|
928
|
-
"ui.show.retracted": "(
|
|
928
|
+
"ui.show.retracted": "(odvoláno: {reason})",
|
|
929
929
|
"ui.show.relof": "{rel} u {who}",
|
|
930
930
|
"ui.show.sex.M": "muž",
|
|
931
931
|
"ui.show.sex.F": "žena",
|
|
@@ -1315,12 +1315,12 @@
|
|
|
1315
1315
|
"ui.phone.qr.url": "adresa pod kódem: {url}",
|
|
1316
1316
|
"ui.phone.qr.more": "další adresa tohoto počítače: strom phone qr --address {url}",
|
|
1317
1317
|
"ui.phone.qr.off": "propojení s telefonem je vypnuté: QR kód žádný (strom phone on)",
|
|
1318
|
-
"ui.phone.qr.app": "QR kód ke spárování telefonu: v aplikaci Strom (Výzkum → Připojit telefon…), nebo strom phone qr v terminálu",
|
|
1318
|
+
"ui.phone.qr.app": "QR kód ke spárování telefonu: v aplikaci Strom (Výzkum → Další → Připojit telefon…), nebo strom phone qr v terminálu",
|
|
1319
1319
|
"ui.phone.notturned": "propojení s telefonem: nezapnuto, nic se nezměnilo",
|
|
1320
1320
|
"ui.error.phone.off": "propojení s telefonem je vypnuté",
|
|
1321
|
-
"ui.error.phone.off.hint": "zapíná se příkazem strom phone on v terminálu, nebo v aplikaci Strom (Výzkum → Připojit telefon…)",
|
|
1321
|
+
"ui.error.phone.off.hint": "zapíná se příkazem strom phone on v terminálu, nebo v aplikaci Strom (Výzkum → Další → Připojit telefon…)",
|
|
1322
1322
|
"ui.error.phone.qr-terminal": "QR kód ke spárování telefonu se ukazuje jen v terminálu nebo v aplikaci Strom",
|
|
1323
|
-
"ui.error.phone.qr-terminal.hint": "strom phone qr v terminálu, nebo Výzkum → Připojit telefon… v aplikaci Strom",
|
|
1323
|
+
"ui.error.phone.qr-terminal.hint": "strom phone qr v terminálu, nebo Výzkum → Další → Připojit telefon… v aplikaci Strom",
|
|
1324
1324
|
"ui.error.phone.address": "server telefonu na tomto počítači nemá adresu {address}",
|
|
1325
1325
|
"ui.error.phone.address.hint": "jeho adresy: {addresses}",
|
|
1326
1326
|
"ui.phone.page.title": "Výzkum Strom",
|
|
@@ -1328,14 +1328,14 @@
|
|
|
1328
1328
|
"ui.phone.page.paired.title": "Spárováno",
|
|
1329
1329
|
"ui.phone.page.paired": "Telefon je spárovaný s výzkumem na počítači. Spárovaný zůstane, dokud se na počítači neodpojí.",
|
|
1330
1330
|
"ui.phone.page.expired.title": "Kód už neplatí",
|
|
1331
|
-
"ui.phone.page.expired": "QR kód spáruje jeden telefon a platí 10 minut. Nový ukáže aplikace Strom na počítači (Výzkum → Připojit telefon…).",
|
|
1331
|
+
"ui.phone.page.expired": "QR kód spáruje jeden telefon a platí 10 minut. Nový ukáže aplikace Strom na počítači (Výzkum → Další → Připojit telefon…).",
|
|
1332
1332
|
"ui.phone.page.unreachable.title": "Počítač neodpovídá",
|
|
1333
1333
|
"ui.phone.page.unreachable": "Je počítač zapnutý, propojení s telefonem zapnuté a telefon ve stejné Wi-Fi?",
|
|
1334
1334
|
"ui.phone.page.retry": "Zkusit znovu",
|
|
1335
1335
|
"ui.phone.page.unpaired.title": "Telefon není spárovaný s tímto počítačem",
|
|
1336
1336
|
"ui.phone.page.unpaired.why": "Telefon byl na počítači odpojen, nebo se změnila adresa počítače, nebo je stránka otevřená bez QR kódu.",
|
|
1337
|
-
"ui.phone.page.unpaired.how": "Na počítači v aplikaci Strom: Výzkum → Připojit telefon a načíst QR kód.",
|
|
1338
|
-
"ui.phone.page.unpaired.howHome": "V ikoně na ploše QR kód načíst nejde. Stránku otevřít v prohlížeči telefonu (Safari, Chrome) načtením QR kódu fotoaparátem (na počítači v aplikaci Strom: Výzkum → Připojit telefon) a odtud ikonu na plochu přidat znovu.",
|
|
1337
|
+
"ui.phone.page.unpaired.how": "Na počítači v aplikaci Strom: Výzkum → Další → Připojit telefon a načíst QR kód.",
|
|
1338
|
+
"ui.phone.page.unpaired.howHome": "V ikoně na ploše QR kód načíst nejde. Stránku otevřít v prohlížeči telefonu (Safari, Chrome) načtením QR kódu fotoaparátem (na počítači v aplikaci Strom: Výzkum → Další → Připojit telefon) a odtud ikonu na plochu přidat znovu.",
|
|
1339
1339
|
"ui.phone.page.unpaired.queue": "{n, plural, one {# neodeslaná fotka čeká v tomto telefonu} few {# neodeslané fotky čekají v tomto telefonu} other {# neodeslaných fotek čeká v tomto telefonu}}",
|
|
1340
1340
|
"ui.phone.page.unpaired.queueBody": "Po novém spárování s tímto počítačem se odešlou samy.",
|
|
1341
1341
|
"ui.phone.page.ago.s": "před {n} s",
|
|
@@ -1766,7 +1766,7 @@
|
|
|
1766
1766
|
"ui.move.cancel": "Zrušit",
|
|
1767
1767
|
"ui.move.cancelled": "Nic se nezaložilo.",
|
|
1768
1768
|
"ui.move.without": "Pokračovat bez prohlížeče: výzkum (nebo Archiv Stromu) ze souboru",
|
|
1769
|
-
"ui.move.without.what": "Aplikace v {from} se k výzkumu nepřipojí: nic z aplikace nepůjde živě – ani výzkum, ani Archiv Stromu. Změny z aplikace jdou do výzkumu souborem (v aplikaci Export → GEDCOM, ve výzkumu strom sync <soubor>), verze výzkumu se do aplikace vrací importem souboru a fotky touto cestou nejdou.",
|
|
1769
|
+
"ui.move.without.what": "Aplikace v {from} se k výzkumu nepřipojí: nic z aplikace nepůjde živě – ani výzkum, ani Archiv Stromu. Změny z aplikace jdou do výzkumu souborem (v aplikaci Export… → GEDCOM, ve výzkumu strom sync <soubor>), verze výzkumu se do aplikace vrací importem souboru a fotky touto cestou nejdou.",
|
|
1770
1770
|
"ui.move.without.later.here": "Plné spojení je jen přes Chrome, Edge, Brave nebo Firefox a {browser} tu je: strom app (v menu Aplikace Strom) v něm kdykoli otevře výzkum a přenos se tím dokončí.",
|
|
1771
1771
|
"ui.move.without.later.none": "Plné spojení je jen přes Chrome, Edge, Brave nebo Firefox: po instalaci některého z nich strom app (v menu Aplikace Strom) otevře výzkum v něm a přenos se tím dokončí.",
|
|
1772
1772
|
"ui.move.nobrowser": "Na tomto počítači není prohlížeč, ze kterého se aplikace Strom k výzkumu připojí. Strom se může přenést do prohlížeče, který to umí – Google Chrome nebo Microsoft Edge, ke stažení zdarma.",
|
|
@@ -2388,8 +2388,10 @@
|
|
|
2388
2388
|
"ui.error.family.needs-reason.hint": "např. --reason \"křest uvádí Jana jako otčíma\"",
|
|
2389
2389
|
"ui.error.person.needs-reason": "změna jména, jeho titulu nebo známého pohlaví potřebuje --reason",
|
|
2390
2390
|
"ui.error.person.needs-reason.hint": "např. --reason \"špatně přečteno: matrika má Novák, ne Nowak\"",
|
|
2391
|
-
"ui.error.retract.needs-reason": "
|
|
2391
|
+
"ui.error.retract.needs-reason": "odvolání potřebuje --reason",
|
|
2392
2392
|
"ui.error.retract.needs-reason.hint": "např. --reason \"špatně přečteno: zápis uvádí Annu, ne Antona\"",
|
|
2393
|
+
"ui.error.name.retracted": "jméno {name} u {id} je odvolané: {reason}",
|
|
2394
|
+
"ui.error.name.retracted.hint": "přece správné: strom name restore {id} \"{name}\" --reason \"…\"",
|
|
2393
2395
|
"ui.error.merge.needs-reason": "sloučení potřebuje --reason",
|
|
2394
2396
|
"ui.error.merge.needs-reason.hint": "--reason \"<proč>\"",
|
|
2395
2397
|
"ui.error.record.needs-reason": "u {id} se mění {fields} — chybí --reason",
|
package/assets/lang/de.json
CHANGED
|
@@ -1315,12 +1315,12 @@
|
|
|
1315
1315
|
"ui.phone.qr.url": "die Adresse unter dem Code: {url}",
|
|
1316
1316
|
"ui.phone.qr.more": "eine weitere Adresse dieses Computers: strom phone qr --address {url}",
|
|
1317
1317
|
"ui.phone.qr.off": "die Verbindung mit dem Telefon ist ausgeschaltet: kein QR-Code (strom phone on)",
|
|
1318
|
-
"ui.phone.qr.app": "der QR-Code zum Koppeln eines Telefons: in der Strom-App (Forschung → Telefon verbinden…) oder strom phone qr im Terminal",
|
|
1318
|
+
"ui.phone.qr.app": "der QR-Code zum Koppeln eines Telefons: in der Strom-App (Forschung → Weitere Aktionen → Telefon verbinden…) oder strom phone qr im Terminal",
|
|
1319
1319
|
"ui.phone.notturned": "Verbindung mit dem Telefon: nicht eingeschaltet, nichts geändert",
|
|
1320
1320
|
"ui.error.phone.off": "die Verbindung mit dem Telefon ist ausgeschaltet",
|
|
1321
|
-
"ui.error.phone.off.hint": "eingeschaltet wird sie mit strom phone on in einem Terminal oder in der Strom-App (Forschung → Telefon verbinden…)",
|
|
1321
|
+
"ui.error.phone.off.hint": "eingeschaltet wird sie mit strom phone on in einem Terminal oder in der Strom-App (Forschung → Weitere Aktionen → Telefon verbinden…)",
|
|
1322
1322
|
"ui.error.phone.qr-terminal": "der QR-Code zum Koppeln eines Telefons wird nur in einem Terminal oder in der Strom-App gezeigt",
|
|
1323
|
-
"ui.error.phone.qr-terminal.hint": "strom phone qr in einem Terminal oder Forschung → Telefon verbinden… in der Strom-App",
|
|
1323
|
+
"ui.error.phone.qr-terminal.hint": "strom phone qr in einem Terminal oder Forschung → Weitere Aktionen → Telefon verbinden… in der Strom-App",
|
|
1324
1324
|
"ui.error.phone.address": "der Telefon-Server dieses Computers hat keine Adresse {address}",
|
|
1325
1325
|
"ui.error.phone.address.hint": "seine Adressen: {addresses}",
|
|
1326
1326
|
"ui.phone.page.title": "Strom-Forschung",
|
|
@@ -1328,14 +1328,14 @@
|
|
|
1328
1328
|
"ui.phone.page.paired.title": "Gekoppelt",
|
|
1329
1329
|
"ui.phone.page.paired": "Das Telefon ist mit der Forschung auf dem Computer gekoppelt. Es bleibt gekoppelt, bis es auf dem Computer getrennt wird.",
|
|
1330
1330
|
"ui.phone.page.expired.title": "Der Code gilt nicht mehr",
|
|
1331
|
-
"ui.phone.page.expired": "Ein QR-Code koppelt ein Telefon und gilt 10 Minuten. Einen neuen zeigt die Strom-App auf dem Computer (Forschung → Telefon verbinden…).",
|
|
1331
|
+
"ui.phone.page.expired": "Ein QR-Code koppelt ein Telefon und gilt 10 Minuten. Einen neuen zeigt die Strom-App auf dem Computer (Forschung → Weitere Aktionen → Telefon verbinden…).",
|
|
1332
1332
|
"ui.phone.page.unreachable.title": "Der Computer antwortet nicht",
|
|
1333
1333
|
"ui.phone.page.unreachable": "Ist der Computer eingeschaltet, die Verbindung mit dem Telefon eingeschaltet und das Telefon im selben WLAN?",
|
|
1334
1334
|
"ui.phone.page.retry": "Erneut versuchen",
|
|
1335
1335
|
"ui.phone.page.unpaired.title": "Dieses Telefon ist nicht mit diesem Computer gekoppelt",
|
|
1336
1336
|
"ui.phone.page.unpaired.why": "Das Telefon wurde am Computer getrennt, die Adresse des Computers hat sich geändert, oder die Seite wurde ohne QR-Code geöffnet.",
|
|
1337
|
-
"ui.phone.page.unpaired.how": "Am Computer in der Strom-App: Forschung → Telefon verbinden und den QR-Code scannen.",
|
|
1338
|
-
"ui.phone.page.unpaired.howHome": "Im Symbol auf dem Home-Bildschirm lässt sich kein QR-Code scannen. Die Seite im Browser des Telefons öffnen (Safari, Chrome), indem der QR-Code mit der Kamera gescannt wird (am Computer in der Strom-App: Forschung → Telefon verbinden), und von dort das Symbol erneut zum Home-Bildschirm hinzufügen.",
|
|
1337
|
+
"ui.phone.page.unpaired.how": "Am Computer in der Strom-App: Forschung → Weitere Aktionen → Telefon verbinden und den QR-Code scannen.",
|
|
1338
|
+
"ui.phone.page.unpaired.howHome": "Im Symbol auf dem Home-Bildschirm lässt sich kein QR-Code scannen. Die Seite im Browser des Telefons öffnen (Safari, Chrome), indem der QR-Code mit der Kamera gescannt wird (am Computer in der Strom-App: Forschung → Weitere Aktionen → Telefon verbinden), und von dort das Symbol erneut zum Home-Bildschirm hinzufügen.",
|
|
1339
1339
|
"ui.phone.page.unpaired.queue": "{n, plural, one {# ungesendetes Foto wartet auf diesem Telefon} other {# ungesendete Fotos warten auf diesem Telefon}}",
|
|
1340
1340
|
"ui.phone.page.unpaired.queueBody": "Nach erneutem Koppeln mit diesem Computer werden sie von selbst gesendet.",
|
|
1341
1341
|
"ui.phone.page.ago.s": "vor {n} s",
|
|
@@ -1766,7 +1766,7 @@
|
|
|
1766
1766
|
"ui.move.cancel": "Abbrechen",
|
|
1767
1767
|
"ui.move.cancelled": "Nichts wurde angelegt.",
|
|
1768
1768
|
"ui.move.without": "Ohne Browser weiter: die Forschung (oder ein Strom-Archiv) aus der Datei",
|
|
1769
|
-
"ui.move.without.what": "Die App in {from} verbindet sich nicht mit der Forschung: nichts aus der App geht live – weder eine Forschung noch ein Strom-Archiv. Änderungen aus der App gehen als Datei in die Forschung (in der App Export → GEDCOM, in der Forschung strom sync <Datei>), die Version der Forschung kommt per Dateiimport zurück, und Fotos gehen diesen Weg nicht.",
|
|
1769
|
+
"ui.move.without.what": "Die App in {from} verbindet sich nicht mit der Forschung: nichts aus der App geht live – weder eine Forschung noch ein Strom-Archiv. Änderungen aus der App gehen als Datei in die Forschung (in der App Export… → GEDCOM, in der Forschung strom sync <Datei>), die Version der Forschung kommt per Dateiimport zurück, und Fotos gehen diesen Weg nicht.",
|
|
1770
1770
|
"ui.move.without.later.here": "Die volle Verbindung gibt es nur über Chrome, Edge, Brave oder Firefox, und {browser} ist hier: strom app (im Menü die Strom-App) öffnet die Forschung jederzeit darin, und die Übertragung ist abgeschlossen.",
|
|
1771
1771
|
"ui.move.without.later.none": "Die volle Verbindung gibt es nur über Chrome, Edge, Brave oder Firefox: sobald einer installiert ist, öffnet strom app (im Menü die Strom-App) die Forschung dort, und die Übertragung ist abgeschlossen.",
|
|
1772
1772
|
"ui.move.nobrowser": "Auf diesem Computer gibt es keinen Browser, aus dem sich die Strom-App mit der Forschung verbindet. Der Stammbaum kann in einen Browser umziehen, der es kann – Google Chrome oder Microsoft Edge, kostenlos herunterzuladen.",
|
|
@@ -2390,6 +2390,8 @@
|
|
|
2390
2390
|
"ui.error.person.needs-reason.hint": "z. B. --reason \"falsch gelesen: im Register steht Novák, nicht Nowak\"",
|
|
2391
2391
|
"ui.error.retract.needs-reason": "Zurückziehen braucht --reason",
|
|
2392
2392
|
"ui.error.retract.needs-reason.hint": "z. B. --reason \"falsch gelesen: der Eintrag nennt Anna, nicht Anton\"",
|
|
2393
|
+
"ui.error.name.retracted": "der Name {name} von {id} ist zurückgezogen: {reason}",
|
|
2394
|
+
"ui.error.name.retracted.hint": "doch richtig: strom name restore {id} \"{name}\" --reason \"…\"",
|
|
2393
2395
|
"ui.error.merge.needs-reason": "Zusammenführen braucht --reason",
|
|
2394
2396
|
"ui.error.merge.needs-reason.hint": "--reason \"<warum>\"",
|
|
2395
2397
|
"ui.error.record.needs-reason": "bei {id} ändert sich {fields} — --reason fehlt",
|
package/dist/cli/ui.js
CHANGED
|
@@ -1215,12 +1215,12 @@ export const UI = {
|
|
|
1215
1215
|
"ui.phone.qr.url": "the address under the code: {url}",
|
|
1216
1216
|
"ui.phone.qr.more": "another address of this computer: strom phone qr --address {url}",
|
|
1217
1217
|
"ui.phone.qr.off": "the phone connection is off: no QR code (strom phone on)",
|
|
1218
|
-
"ui.phone.qr.app": "the QR code to pair a phone: in the Strom app (Research → Connect phone…), or strom phone qr in a terminal",
|
|
1218
|
+
"ui.phone.qr.app": "the QR code to pair a phone: in the Strom app (Research → Other actions → Connect phone…), or strom phone qr in a terminal",
|
|
1219
1219
|
"ui.phone.notturned": "phone connection: not turned on, nothing changed",
|
|
1220
1220
|
"ui.error.phone.off": "the phone connection is off",
|
|
1221
|
-
"ui.error.phone.off.hint": "it is turned on by strom phone on in a terminal, or in the Strom app (Research → Connect phone…)",
|
|
1221
|
+
"ui.error.phone.off.hint": "it is turned on by strom phone on in a terminal, or in the Strom app (Research → Other actions → Connect phone…)",
|
|
1222
1222
|
"ui.error.phone.qr-terminal": "the QR code to pair a phone is shown only in a terminal or in the Strom app",
|
|
1223
|
-
"ui.error.phone.qr-terminal.hint": "strom phone qr in a terminal, or Research → Connect phone… in the Strom app",
|
|
1223
|
+
"ui.error.phone.qr-terminal.hint": "strom phone qr in a terminal, or Research → Other actions → Connect phone… in the Strom app",
|
|
1224
1224
|
"ui.error.phone.address": "the phone's server of this computer has no address {address}",
|
|
1225
1225
|
"ui.error.phone.address.hint": "its addresses: {addresses}",
|
|
1226
1226
|
"ui.phone.page.title": "Strom research",
|
|
@@ -1228,14 +1228,14 @@ export const UI = {
|
|
|
1228
1228
|
"ui.phone.page.paired.title": "Paired",
|
|
1229
1229
|
"ui.phone.page.paired": "This phone is paired with the research on the computer. It stays paired until it is disconnected on the computer.",
|
|
1230
1230
|
"ui.phone.page.expired.title": "The code no longer holds",
|
|
1231
|
-
"ui.phone.page.expired": "A QR code pairs one phone, within 10 minutes. A new one is shown by the Strom app on the computer (Research → Connect phone…).",
|
|
1231
|
+
"ui.phone.page.expired": "A QR code pairs one phone, within 10 minutes. A new one is shown by the Strom app on the computer (Research → Other actions → Connect phone…).",
|
|
1232
1232
|
"ui.phone.page.unreachable.title": "The computer does not answer",
|
|
1233
1233
|
"ui.phone.page.unreachable": "Is the computer on, the phone connection turned on, and the phone on the same Wi-Fi?",
|
|
1234
1234
|
"ui.phone.page.retry": "Try again",
|
|
1235
1235
|
"ui.phone.page.unpaired.title": "This phone is not paired with this computer",
|
|
1236
1236
|
"ui.phone.page.unpaired.why": "The phone was unpaired on the computer, the computer’s address changed, or the page was opened without the QR code.",
|
|
1237
|
-
"ui.phone.page.unpaired.how": "On the computer in the Strom app: Research → Connect phone, then scan the QR code.",
|
|
1238
|
-
"ui.phone.page.unpaired.howHome": "The icon on the home screen cannot scan a QR code. The page is opened in the phone’s browser (Safari, Chrome) by the QR code scanned with the camera (on the computer in the Strom app: Research → Connect phone); from there the icon is added to the home screen again.",
|
|
1237
|
+
"ui.phone.page.unpaired.how": "On the computer in the Strom app: Research → Other actions → Connect phone, then scan the QR code.",
|
|
1238
|
+
"ui.phone.page.unpaired.howHome": "The icon on the home screen cannot scan a QR code. The page is opened in the phone’s browser (Safari, Chrome) by the QR code scanned with the camera (on the computer in the Strom app: Research → Other actions → Connect phone); from there the icon is added to the home screen again.",
|
|
1239
1239
|
"ui.phone.page.unpaired.queue": "{n, plural, one {# unsent photo is waiting on this phone} other {# unsent photos are waiting on this phone}}",
|
|
1240
1240
|
"ui.phone.page.unpaired.queueBody": "They are sent automatically after pairing with this computer again.",
|
|
1241
1241
|
"ui.phone.page.ago.s": "{n} s ago",
|
|
@@ -1666,7 +1666,7 @@ export const UI = {
|
|
|
1666
1666
|
"ui.move.cancel": "Cancel",
|
|
1667
1667
|
"ui.move.cancelled": "Nothing was set up.",
|
|
1668
1668
|
"ui.move.without": "Go on without a browser: the research (or a Strom archive) made from the file",
|
|
1669
|
-
"ui.move.without.what": "The app in {from} does not connect to the research: nothing of the app goes live — neither a research nor a Strom archive. Changes from the app go to the research as a file (Export → GEDCOM in the app, strom sync <file> in the research), the research's version comes back by importing a file, and photos do not go that way.",
|
|
1669
|
+
"ui.move.without.what": "The app in {from} does not connect to the research: nothing of the app goes live — neither a research nor a Strom archive. Changes from the app go to the research as a file (Export… → GEDCOM in the app, strom sync <file> in the research), the research's version comes back by importing a file, and photos do not go that way.",
|
|
1670
1670
|
"ui.move.without.later.here": "The full connection is only through Chrome, Edge, Brave or Firefox, and {browser} is here: strom app (the menu's Strom app) opens the research in it at any time, and the move is finished.",
|
|
1671
1671
|
"ui.move.without.later.none": "The full connection is only through Chrome, Edge, Brave or Firefox: once one is installed, strom app (the menu's Strom app) opens the research there and the move is finished.",
|
|
1672
1672
|
"ui.move.nobrowser": "This computer has no browser the Strom app connects to the research from. The tree can move to one that can — Google Chrome or Microsoft Edge, free to download.",
|
|
@@ -2167,6 +2167,8 @@ export const UI = {
|
|
|
2167
2167
|
"ui.error.person.needs-reason.hint": "e.g. --reason \"misread: the register has Novák, not Nowak\"",
|
|
2168
2168
|
"ui.error.retract.needs-reason": "retracting needs --reason",
|
|
2169
2169
|
"ui.error.retract.needs-reason.hint": "e.g. --reason \"misread: the entry names Anna, not Anton\"",
|
|
2170
|
+
"ui.error.name.retracted": "the name {name} of {id} is retracted: {reason}",
|
|
2171
|
+
"ui.error.name.retracted.hint": "right after all: strom name restore {id} \"{name}\" --reason \"…\"",
|
|
2170
2172
|
"ui.error.merge.needs-reason": "merging needs --reason",
|
|
2171
2173
|
"ui.error.merge.needs-reason.hint": "--reason \"<why>\"",
|
|
2172
2174
|
"ui.error.record.needs-reason": "changing {fields} of {id} needs --reason",
|
package/dist/commands/output.js
CHANGED
|
@@ -13,7 +13,7 @@ import { UsageError } from "../core/errors.js";
|
|
|
13
13
|
import { excerptSettings, planExcerpts } from "../core/excerpt.js";
|
|
14
14
|
import { runGit, tracked } from "../core/git.js";
|
|
15
15
|
import { Settings } from "../core/config.js";
|
|
16
|
-
import { appKnowsArchive, appKnowsNoCouple, appShowsHypothesisLinks, appShowsReadings, appDecidesConflicts, appOpensLinks, appReadsTitles, appShowsCoupleEvents, appShowsEdges, appShowsSourceReads, appShowsFactStatus, appShowsStoryDrafts, appTurnsExcerpts } from "../core/stromapp.js";
|
|
16
|
+
import { appKnowsArchive, appKnowsNoCouple, appShowsHypothesisLinks, appShowsReadings, appShowsOmittedImages, appDecidesConflicts, appOpensLinks, appReadsTitles, appShowsCoupleEvents, appShowsEdges, appShowsSourceReads, appShowsFactStatus, appShowsStoryDrafts, appTurnsExcerpts } from "../core/stromapp.js";
|
|
17
17
|
import { EXCERPT_QUALITIES, EXCERPT_SCOPES } from "../core/model.js";
|
|
18
18
|
import { ui } from "../cli/ui.js";
|
|
19
19
|
import { isAgent } from "../core/which.js";
|
|
@@ -93,7 +93,9 @@ export function writeTreeGed(tree, opts) {
|
|
|
93
93
|
const conflictSides = opts.for === "strom" && appDecidesConflicts(new Settings(tree.env, {}), opts.stromVersion);
|
|
94
94
|
// …and the reading of a document each source is an entry of, for an app that opens it
|
|
95
95
|
const readings = opts.for === "strom" && appShowsReadings(new Settings(tree.env, {}), opts.stromVersion);
|
|
96
|
-
|
|
96
|
+
// …and why a source has no image though the research has one, for an app that says so and asks for it
|
|
97
|
+
const omitted = !!images && appShowsOmittedImages(new Settings(tree.env, {}), opts.stromVersion);
|
|
98
|
+
const result = exportGedcom(tree, { for: opts.for, stromVersion: opts.stromVersion, ...(persons ? { persons } : {}), ...(images ? { excerpts: images.of } : {}), ...(clips ? { clips } : {}), ...(research ? { research } : {}), ...(edges ? { edges } : {}), ...(storyDrafts ? { storyDrafts } : {}), ...(coupleResi ? { coupleResi } : {}), ...(sourceReads ? { sourceReads } : {}), ...(factStatus ? { factStatus } : {}), ...(archive ? { archive } : {}), ...(turnsExcerpts ? { turnsExcerpts } : {}), ...(noCouple ? { noCouple } : {}), ...(titles ? { titles } : {}), ...(hypothesisLinks ? { hypothesisLinks } : {}), ...(conflictSides ? { conflictSides } : {}), ...(readings ? { readings } : {}), ...(omitted ? { omitted: images.omitted } : {}) });
|
|
97
99
|
const findings = validateGedcom(result.text, opts.for === "standard" ? { strict: true } : {});
|
|
98
100
|
const file = opts.out ?? gedFile(tree, opts.for, opts.research);
|
|
99
101
|
if (!hasGedErrors(findings) && !tree.dryRun) {
|
package/dist/commands/people.js
CHANGED
|
@@ -411,6 +411,7 @@ register({
|
|
|
411
411
|
throw new UsageError(`the name ${gedcomName(gone)} of ${p.id} was retracted: ${gone.retracted.reason}`, {
|
|
412
412
|
hint: `right after all: strom name restore ${p.id} "${gedcomName(gone)}" --reason "…"`,
|
|
413
413
|
code: "name.retracted",
|
|
414
|
+
params: { name: gedcomName(gone), id: p.id, reason: gone.retracted.reason },
|
|
414
415
|
});
|
|
415
416
|
const r = addName(tree, p.id, { name: args[1], kind: opts.kind, citation: citationOf(opts), primary: Boolean(opts.primary), prefix: opts.prefix, suffix: opts.suffix });
|
|
416
417
|
return { text: written(tree), data: { person: r.person, name: r.name } };
|
package/dist/commands/phone.js
CHANGED
|
@@ -111,13 +111,13 @@ register({
|
|
|
111
111
|
description: "The phone's camera opens the page of the phone's server on this computer and pairs it (the same Wi-Fi). The code\n" +
|
|
112
112
|
"holds 10 minutes, for one phone; shown again meanwhile, the same code. Only in the user's own terminal — never\n" +
|
|
113
113
|
"with --json or without a terminal: the code is a phone's way into the research (the Strom app shows it too:\n" +
|
|
114
|
-
"Research → Connect phone…). The page is in the research language.",
|
|
114
|
+
"Research → Other actions → Connect phone…). The page is in the research language.",
|
|
115
115
|
options: [{ name: "address", type: "string", value: "<url>", description: "another address of this computer (strom phone says them), e.g. a cable's beside the Wi-Fi" }],
|
|
116
116
|
examples: ["strom phone qr", "strom phone qr --address http://192.168.0.5:47800"],
|
|
117
117
|
async run(ctx, { opts }) {
|
|
118
118
|
const lang = ctx.uiLang();
|
|
119
119
|
if (!showsQr(ctx))
|
|
120
|
-
throw new StromError("the QR code to pair a phone is shown in the user's own terminal or in the Strom app, never to an agent", { hint: "the user runs strom phone qr in their terminal, or Research → Connect phone… in the Strom app", code: "phone.qr-terminal" });
|
|
120
|
+
throw new StromError("the QR code to pair a phone is shown in the user's own terminal or in the Strom app, never to an agent", { hint: "the user runs strom phone qr in their terminal, or Research → Other actions → Connect phone… in the Strom app", code: "phone.qr-terminal" });
|
|
121
121
|
const s = await withAddresses(ctx);
|
|
122
122
|
if (s.state !== "on" || !s.addresses.length)
|
|
123
123
|
return { text: s.state === "on" || s.state === "error" ? stateLines(lang, s) : ui(lang, "ui.phone.qr.off"), data: { state: s.state } };
|
package/dist/commands/read.js
CHANGED
|
@@ -31,7 +31,7 @@ import { recordReader, tokensOf, usageOpt } from "../core/metrics.js";
|
|
|
31
31
|
import { readerLimit } from "../core/readstats.js";
|
|
32
32
|
import { guardIndexFirst, INDEX_FIRST_DEFAULT } from "../core/indexfirst.js";
|
|
33
33
|
import { bookViewSizes, readingOf, treeTuning, tuningOn } from "../core/tune.js";
|
|
34
|
-
import { claimStem, readerAgent, readerDesk, refuseReadersInSandbox } from "./readers.js";
|
|
34
|
+
import { claimStem, noReaderFor, readerAgent, readerDesk, refuseReadersInSandbox } from "./readers.js";
|
|
35
35
|
import { noReaderHere, refusedBySandbox } from "../core/sandbox.js";
|
|
36
36
|
import { activeFetches } from "../core/fetching.js";
|
|
37
37
|
import { finishOf } from "../core/clock.js";
|
|
@@ -243,7 +243,7 @@ register({
|
|
|
243
243
|
const agentId = readerAgent(ctx, tree);
|
|
244
244
|
const runner = RUNNERS[agentId];
|
|
245
245
|
if (!runner)
|
|
246
|
-
throw
|
|
246
|
+
throw noReaderFor(agentId, "strom read");
|
|
247
247
|
if (agentId !== "script" && !which(runner.command, ctx.env))
|
|
248
248
|
throw new StromError(`${runner.command} is not installed`);
|
|
249
249
|
const model = typeof opts.model === "string" ? opts.model : ctx.settings.models(agentId, tree.config).vision;
|
|
@@ -440,7 +440,8 @@ register({
|
|
|
440
440
|
const own = path.join(work, `${stem}-${k + 1}`);
|
|
441
441
|
fs.mkdirSync(own, { recursive: true });
|
|
442
442
|
const settingsFile = path.join(own, "reader-settings.json");
|
|
443
|
-
|
|
443
|
+
const seen = group.flatMap((g) => [g.view, ...(g.parts ?? []).map((p) => p.view)]);
|
|
444
|
+
fs.writeFileSync(settingsFile, JSON.stringify(readerSettings(seen, report, permissionPath), null, 2));
|
|
444
445
|
const context = typeof opts.context === "string" && opts.context.trim() ? `Context: ${opts.context.trim().replace(/\s*\n\s*/g, " ")}\n` : "";
|
|
445
446
|
// a blind reading says so in its head: its "unclear" over a place the researcher looked at before is a check
|
|
446
447
|
const head = `# Reading ${label} · batch ${k + 1}${fetching ? "" : ` of ${groups.length}`}\nQuestion: ${question.replace(/\s*\n\s*/g, " ")}\n${context}${opts.blind ? "Blind: yes\n" : ""}\n${NEXT_BLOCK}\n`;
|
|
@@ -459,6 +460,7 @@ register({
|
|
|
459
460
|
env: { ...withoutAgentMarks(env), STROM_NONINTERACTIVE: "1", STROM_READER: "1" },
|
|
460
461
|
settingsFile,
|
|
461
462
|
reader: true,
|
|
463
|
+
readerFiles: { views: seen, report },
|
|
462
464
|
// without the user's own add-ons (skills, plugins, MCP servers) unless they said otherwise
|
|
463
465
|
...(ctx.settings.agentAddons(tree.config) ? {} : { clean: true }),
|
|
464
466
|
timeoutMs: minutes * 60_000,
|
package/dist/commands/readers.js
CHANGED
|
@@ -76,6 +76,11 @@ export function claimStem(root, prefix, base, taken) {
|
|
|
76
76
|
}
|
|
77
77
|
return `${base}-${process.pid}`;
|
|
78
78
|
}
|
|
79
|
+
/** An agent strom has no reader for: the agents that read said (each agent of a research does), none of them preferred. */
|
|
80
|
+
export function noReaderFor(agentId, command) {
|
|
81
|
+
const agents = Object.keys(RUNNERS).filter((a) => a !== "script");
|
|
82
|
+
return new UsageError(`no reader for agent "${agentId}"`, { hint: `${command} reads with ${agents.join(", ")}: ${command} … --agent <one of them>` });
|
|
83
|
+
}
|
|
79
84
|
/** Inside a sandbox that lets no agent start (Codex's) no reader is started: said at once, with what to do instead. */
|
|
80
85
|
export function refuseReadersInSandbox(ctx, command) {
|
|
81
86
|
const sb = sandboxOf(ctx.env);
|
|
@@ -92,7 +97,7 @@ export function readers(ctx, tree, shared, kind, first, opts, reportsAt, own = {
|
|
|
92
97
|
const agentId = readerAgent(ctx, tree);
|
|
93
98
|
const runner = RUNNERS[agentId];
|
|
94
99
|
if (!runner)
|
|
95
|
-
throw
|
|
100
|
+
throw noReaderFor(agentId, `strom ${kind}`);
|
|
96
101
|
if (agentId !== "script" && !which(runner.command, ctx.env))
|
|
97
102
|
throw new StromError(`${runner.command} is not installed`);
|
|
98
103
|
const model = typeof opts.model === "string" ? opts.model : ctx.settings.models(agentId, tree.config).vision;
|
|
@@ -135,6 +140,7 @@ export function readers(ctx, tree, shared, kind, first, opts, reportsAt, own = {
|
|
|
135
140
|
env: { ...withoutAgentMarks(env), STROM_NONINTERACTIVE: "1", STROM_READER: "1" },
|
|
136
141
|
settingsFile,
|
|
137
142
|
reader: true,
|
|
143
|
+
readerFiles: { views, report },
|
|
138
144
|
// without the user's own add-ons (skills, plugins, MCP servers) unless they said otherwise
|
|
139
145
|
...(ctx.settings.agentAddons(tree.config) ? {} : { clean: true }),
|
|
140
146
|
timeoutMs: limit.minutes * 60_000,
|
package/dist/commands/sync.js
CHANGED
|
@@ -344,7 +344,7 @@ register({
|
|
|
344
344
|
throw new UsageError("--only goes with --apply");
|
|
345
345
|
return {
|
|
346
346
|
text: lines(got ? ui(lang, "ui.sync.got") : undefined, planText(tree, plan, incoming, shownAs, lang, edits)),
|
|
347
|
-
data: { ...(got ? { received: got } : {}), base: plan.base, head: plan.head ?? null, partial: plan.partial, changes: plan.changes, strangers: plan.identity.strangers },
|
|
347
|
+
data: { ...(got ? { received: got } : {}), base: plan.base, head: plan.head ?? null, partial: plan.partial, changes: plan.changes, strangers: plan.identity.strangers, ...(plan.mended ? { mended: plan.mended } : {}) },
|
|
348
348
|
};
|
|
349
349
|
}
|
|
350
350
|
const only = numbers(opts.only, plan.changes.length);
|
package/dist/core/changelog.js
CHANGED
|
@@ -155,7 +155,38 @@ export function factSaid(tree, owner, eventId, lang) {
|
|
|
155
155
|
const what = [f.value, humanDate(f.date, lang), humanPlace(f.place, f.house, lang)].filter(Boolean).join(", ");
|
|
156
156
|
return `${eventName(f.kind, lang, f.label)}${what ? `: ${what}` : ""}`;
|
|
157
157
|
}
|
|
158
|
-
/**
|
|
158
|
+
/** How many sources a line of the history names at most (the Strom app opens each from it). */
|
|
159
|
+
export const LINE_SOURCES_MAX = 20;
|
|
160
|
+
/** A source named by its ID in a summary of any script (never \b, which knows only ASCII letters). */
|
|
161
|
+
const SOURCE_IN = /(?<![\p{L}\p{M}\p{N}])S\d+(?![\p{L}\p{M}\p{N}])/gu;
|
|
162
|
+
/**
|
|
163
|
+
* The sources an operation is about, by the IDs the research has them under now: those it changed (its targets) and,
|
|
164
|
+
* a citation, those it cites or cites no more (its summary names them), a fact added, those it cites now — a source
|
|
165
|
+
* merged into another as that one.
|
|
166
|
+
*/
|
|
167
|
+
function sourcesOf(tree, o) {
|
|
168
|
+
const ids = o.targets.filter((t) => /^S\d+$/.test(t));
|
|
169
|
+
if (/\.cite$/.test(o.op))
|
|
170
|
+
ids.push(...(o.summary.match(SOURCE_IN) ?? []));
|
|
171
|
+
// a fact added: the sources it cites (as it stands now — what the app would open to check it)
|
|
172
|
+
if (o.op === "event.add") {
|
|
173
|
+
const owner = tree.get(o.targets[0] ?? "");
|
|
174
|
+
const fact = owner?.events.find((e) => e.id === o.targets[1]);
|
|
175
|
+
if (fact && !fact.retracted)
|
|
176
|
+
ids.push(...fact.citations.map((c) => c.source));
|
|
177
|
+
}
|
|
178
|
+
const now = ids.map((id) => {
|
|
179
|
+
let r = tree.get(id);
|
|
180
|
+
for (let hops = 0; r?.mergedInto && hops < 10; hops++)
|
|
181
|
+
r = tree.get(r.mergedInto) ?? r;
|
|
182
|
+
return r?.id ?? id;
|
|
183
|
+
});
|
|
184
|
+
return [...new Set(now)].slice(0, LINE_SOURCES_MAX);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Lines of what a commit saved, in the research language, each with what it is about and the sources it names (for
|
|
188
|
+
* the Strom app to open them: /log `sources`); its subject when it logged no operation.
|
|
189
|
+
*/
|
|
159
190
|
export function changeLines(tree, ops, subject, lang, was) {
|
|
160
191
|
const get = (id) => (id ? tree.get(id) : undefined);
|
|
161
192
|
const who = (id) => {
|
|
@@ -231,9 +262,18 @@ export function changeLines(tree, ops, subject, lang, was) {
|
|
|
231
262
|
};
|
|
232
263
|
const out = [];
|
|
233
264
|
let kind = "other";
|
|
265
|
+
let cites = [];
|
|
234
266
|
const say = (line) => {
|
|
235
|
-
if (
|
|
236
|
-
|
|
267
|
+
if (!line)
|
|
268
|
+
return;
|
|
269
|
+
const had = out.find((l) => l.text === line);
|
|
270
|
+
if (!had)
|
|
271
|
+
out.push({ text: line, kind, ...(cites.length ? { sources: cites } : {}) });
|
|
272
|
+
// the same line of another operation: its sources too
|
|
273
|
+
else
|
|
274
|
+
for (const id of cites)
|
|
275
|
+
if (!had.sources?.includes(id) && (had.sources?.length ?? 0) < LINE_SOURCES_MAX)
|
|
276
|
+
had.sources = [...(had.sources ?? []), id];
|
|
237
277
|
};
|
|
238
278
|
// Images downloaded: one line for each book, whatever their order.
|
|
239
279
|
const images = new Map();
|
|
@@ -241,6 +281,7 @@ export function changeLines(tree, ops, subject, lang, was) {
|
|
|
241
281
|
if (QUIET.has(o.op))
|
|
242
282
|
continue;
|
|
243
283
|
kind = kindOf(o.op);
|
|
284
|
+
cites = sourcesOf(tree, o);
|
|
244
285
|
const [first, second] = o.targets;
|
|
245
286
|
if (o.op === "media.add") {
|
|
246
287
|
// a part of an image fetched sharper is no new scan: said as a part of its image, apart from the new scans
|
|
@@ -376,9 +417,9 @@ export function changeLines(tree, ops, subject, lang, was) {
|
|
|
376
417
|
const key = SAID[o.op];
|
|
377
418
|
say(key ? phrase(lang, key, { who: who(first), name: name(first) }) : changed(o));
|
|
378
419
|
}
|
|
379
|
-
const lines = out.map(({ text: line, kind }) => {
|
|
420
|
+
const lines = out.map(({ text: line, kind, sources }) => {
|
|
380
421
|
if (!line.startsWith("\u0000media:"))
|
|
381
|
-
return { text: line, kind };
|
|
422
|
+
return { text: line, kind, ...(sources ? { sources } : {}) };
|
|
382
423
|
const key = line.slice("\u0000media:".length);
|
|
383
424
|
const part = key.startsWith("part:");
|
|
384
425
|
const book = key.slice(key.indexOf(":") + 1);
|