strom-research 1.15.0-beta.4 → 1.15.0-beta.6
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 +45 -0
- package/CHANGELOG.de.md +49 -0
- package/CHANGELOG.md +45 -0
- package/README.md +3 -1
- package/assets/lang/cs.json +2 -0
- package/assets/lang/de.json +2 -0
- package/assets/method/core.md +3 -0
- package/assets/method/reading.md +7 -0
- package/dist/brief/brief.js +19 -0
- package/dist/brief/sheet.js +2 -2
- package/dist/cli/commit.js +6 -3
- package/dist/cli/execute.js +2 -2
- package/dist/cli/main.js +21 -5
- package/dist/cli/ui.js +2 -0
- package/dist/commands/batch.js +1 -1
- package/dist/commands/calibrate.js +1 -0
- package/dist/commands/connectors.js +515 -93
- package/dist/commands/guide.js +1 -1
- package/dist/commands/media.js +10 -4
- package/dist/commands/read.js +183 -13
- package/dist/commands/setup.js +4 -2
- package/dist/core/connector.js +14 -2
- package/dist/core/fetching.js +215 -0
- package/dist/core/git.js +10 -4
- package/dist/core/live.js +12 -3
- package/dist/core/net.js +86 -0
- package/dist/core/readstats.js +21 -0
- package/dist/core/terms.js +4 -0
- package/dist/core/tree.js +18 -1
- package/dist/core/update.js +14 -0
- package/dist/core/webgate.js +1 -1
- package/dist/core/whatsnew.js +79 -0
- package/package.json +7 -4
package/CHANGELOG.cs.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Co je nového ve Strom výzkumu
|
|
2
|
+
|
|
3
|
+
[English](CHANGELOG.md) · Čeština · [Deutsch](CHANGELOG.de.md)
|
|
4
|
+
|
|
5
|
+
Změny každé verze ve zkratce. Úplné poznámky a instalační řádky jsou na
|
|
6
|
+
[GitHub Releases](https://github.com/ACiDekCZ/strom-research/releases) (anglicky).
|
|
7
|
+
|
|
8
|
+
## 1.15.0
|
|
9
|
+
|
|
10
|
+
*Patří k aplikaci Strom 3.12.0.*
|
|
11
|
+
|
|
12
|
+
- **Archiv Stromu podle volby, i s AI agentem.** Průvodce nastavením se ptá, zda nové rodokmeny budou výzkumem
|
|
13
|
+
s agentem, nebo jen Archivem Stromu; v nastavení jde volbu změnit pro jeden rodokmen nebo pro nové.
|
|
14
|
+
- **Výzkum čeká na svého agenta.** Rodokmen, jehož AI agent na tomto počítači není, ukládá, co posílá aplikace Strom,
|
|
15
|
+
jako Archiv Stromu. Jakmile je agent nainstalovaný, výzkum pokračuje sám.
|
|
16
|
+
- **Jedna kniha archivu se stahuje jednou.** Kniha, která už ve výzkumu je, se pojmenuje místo nového zápisu
|
|
17
|
+
a stahování, takže archiv nikdy nedostane dvakrát žádost o tytéž snímky.
|
|
18
|
+
- **Rychlejší čtení.** Snímky čte současně pět čtenářů (nastavení `read.parallel`, 1 až 10) a dlouhé stahování
|
|
19
|
+
ukazuje, kolik už je hotovo („40/109 snímků“). Čtenáři začnou už během stahování knihy: snímky se registrují
|
|
20
|
+
po deseti a co nepřišlo, je řečeno přesně; Ctrl-C ponechá, co už přišlo. Archiv dostane stejné žádosti ve stejném
|
|
21
|
+
tempu. Kniha se může stahovat i na pozadí, zatímco agent pracuje dál (`strom fetch --background`), nikdy z archivu,
|
|
22
|
+
který dovoluje jen tempo člověka. Hledání jednoho zápisu může skončit u nálezu (`strom read --until-found`):
|
|
23
|
+
přečtené snímky jsou řečeny přesně a jen ty se počítají jako prohledané.
|
|
24
|
+
- **Rodokmeny z jiných programů.** Soubor GEDCOM uložený se značkou BOM nebo v UTF-16 (tak ho ukládají některé programy
|
|
25
|
+
ve Windows) se čte jako rodokmen; rodokmen jiného výzkumu se převezme jako cizí.
|
|
26
|
+
- **Živé sledování končí čistě** na každém systému, i ve Windows, a aplikace Strom se dozví, že skončilo.
|
|
27
|
+
- **Jeden strom na instalaci.** Jiný strom na stejném počítači (z npm nebo sestavený ze zdrojů) nikdy nepřevezme odkazy
|
|
28
|
+
aplikace Strom ani kanál aktualizací.
|
|
29
|
+
- **Co je nového.** Po `strom update` a u `strom --version` odkaz na tento přehled v jazyce výzkumu. Aplikace Strom
|
|
30
|
+
ukazuje body nové verze výzkumu ve svém okně „Co je nového“.
|
|
31
|
+
|
|
32
|
+
## 1.14.0
|
|
33
|
+
|
|
34
|
+
*11. 10. 2026 · patří k aplikaci Strom 3.11.0.*
|
|
35
|
+
|
|
36
|
+
- **Podmínky každého archivu.** strom dodržuje, jak daleko každý archiv dovoluje automatický přístup: povoleno,
|
|
37
|
+
omezeně, jen ručně, nebo vůbec. Kde podmínky nejsou jasné, rozhodne jednou člověk. Odmítnutí archiv na den odloží.
|
|
38
|
+
- **Co čeká, po místech.** Věci pro člověka jsou seřazené podle druhu a seskupené podle toho, kde se vyřizují: jeden
|
|
39
|
+
archiv, jeden úřad, rodina, jeden web. Dopis nebo dotaz jde označit jako odeslaný.
|
|
40
|
+
- **Čtení starého písma.** Snímky ve velikosti, jakou každý pohled potřebuje, čtenář snímků na modelu, který si člověk
|
|
41
|
+
zvolil, a čtení vyladěné na vlastních doložených záznamech výzkumu.
|
|
42
|
+
- **S aplikací Strom 3.11.0.** Rozpor mezi úpravou v aplikaci a záznamem se rozhoduje v aplikaci; hypotézy ukazují, co
|
|
43
|
+
by která varianta spojila.
|
|
44
|
+
- **Menší podklady pro agenta, které vědí víc**, a míra uvažování je volbou člověka (`model.effort`).
|
|
45
|
+
- **`strom grep`** prohledává podklady, poznámky a výstupy výzkumu, i bez ohledu na diakritiku.
|
package/CHANGELOG.de.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Was ist neu in Strom Ahnenforschung
|
|
2
|
+
|
|
3
|
+
[English](CHANGELOG.md) · [Čeština](CHANGELOG.cs.md) · Deutsch
|
|
4
|
+
|
|
5
|
+
Die Änderungen jeder Version in Kürze. Die vollständigen Hinweise und die Installationszeilen stehen bei
|
|
6
|
+
[GitHub Releases](https://github.com/ACiDekCZ/strom-research/releases) (auf Englisch).
|
|
7
|
+
|
|
8
|
+
## 1.15.0
|
|
9
|
+
|
|
10
|
+
*Gehört zur Strom-App 3.12.0.*
|
|
11
|
+
|
|
12
|
+
- **Ein Strom-Archiv nach Wahl, auch mit einem KI-Agenten.** Die Einrichtung fragt, ob neue Stammbäume Forschungen mit
|
|
13
|
+
dem Agenten sind oder nur ein Strom-Archiv; in den Einstellungen lässt sich das für einen Stammbaum oder für die
|
|
14
|
+
neuen ändern.
|
|
15
|
+
- **Eine Forschung wartet auf ihren Agenten.** Ein Stammbaum, dessen KI-Agent nicht auf diesem Computer ist, speichert,
|
|
16
|
+
was die Strom-App sendet, wie ein Strom-Archiv. Sobald der Agent installiert ist, geht die Forschung von selbst weiter.
|
|
17
|
+
- **Ein Buch eines Archivs, einmal geladen.** Ein Buch, das schon in der Forschung ist, wird genannt, statt neu
|
|
18
|
+
eingetragen und wieder geladen zu werden – ein Archiv wird nie zweimal um dieselben Bilder gebeten.
|
|
19
|
+
- **Schneller lesen.** Fünf Leser lesen die Scans gleichzeitig (die Einstellung `read.parallel`, 1 bis 10), und ein
|
|
20
|
+
langer Download zeigt, wie weit er ist („40/109 Bilder“). Die Leser beginnen schon, während ein Buch lädt: seine
|
|
21
|
+
Bilder werden zu zehnt registriert, und was nicht kam, wird genau gesagt; Strg+C behält, was schon kam. Ein Archiv
|
|
22
|
+
bekommt dieselben Anfragen im selben Tempo wie bisher. Ein Buch kann auch im Hintergrund laden, während der Agent
|
|
23
|
+
weiterarbeitet (`strom fetch --background`), nie aus einem Archiv, das nur das Tempo eines Menschen erlaubt. Die
|
|
24
|
+
Suche nach einem Eintrag kann beim Fund enden (`strom read --until-found`): die gelesenen Bilder werden genau gesagt,
|
|
25
|
+
und nur sie gelten als durchsucht.
|
|
26
|
+
- **Stammbäume aus anderen Programmen.** Eine GEDCOM-Datei mit Byte-Order-Mark oder in UTF-16 (so speichern sie manche
|
|
27
|
+
Windows-Programme) wird als Stammbaum gelesen; der Stammbaum einer anderen Forschung wird als fremder übernommen.
|
|
28
|
+
- **Die Live-Ansicht endet sauber** auf jedem System, auch unter Windows, und die Strom-App erfährt, dass sie endete.
|
|
29
|
+
- **Ein strom pro Installation.** Ein anderer strom auf demselben Computer (aus npm oder aus den Quellen gebaut)
|
|
30
|
+
übernimmt nie die Links der Strom-App oder den Update-Kanal.
|
|
31
|
+
- **Was ist neu.** Nach `strom update` und bei `strom --version` ein Link zu dieser Übersicht in der Sprache der
|
|
32
|
+
Forschung. Die Strom-App zeigt die Punkte einer neuen Forschungsversion in ihrem Fenster „Was ist neu“.
|
|
33
|
+
|
|
34
|
+
## 1.14.0
|
|
35
|
+
|
|
36
|
+
*11.10.2026 · gehört zur Strom-App 3.11.0.*
|
|
37
|
+
|
|
38
|
+
- **Die Bedingungen jedes Archivs.** strom hält sich daran, wie weit jedes Archiv automatischen Zugriff erlaubt:
|
|
39
|
+
erlaubt, eingeschränkt, nur von Hand oder gar nicht. Wo die Bedingungen unklar sind, entscheidet einmal der Mensch.
|
|
40
|
+
Eine Ablehnung pausiert ein Archiv für einen Tag.
|
|
41
|
+
- **Was wartet, nach Orten.** Die Dinge für den Menschen sind nach Art sortiert und danach gruppiert, wo sie erledigt
|
|
42
|
+
werden: ein Archiv, ein Amt, die Familie, eine Website. Ein Brief oder eine Frage lässt sich als verschickt markieren.
|
|
43
|
+
- **Alte Handschrift lesen.** Scans in der Größe, die jede Ansicht braucht, ein Leser der Scans auf dem Modell, das der
|
|
44
|
+
Mensch gewählt hat, und das Lesen abgestimmt auf die eigenen belegten Einträge der Forschung.
|
|
45
|
+
- **Mit der Strom-App 3.11.0.** Ein Widerspruch zwischen einer Änderung in der App und einem Eintrag wird in der App
|
|
46
|
+
entschieden; Hypothesen zeigen, was jede Variante verbinden würde.
|
|
47
|
+
- **Kleinere Unterlagen für den Agenten, die mehr wissen**, und der Denkaufwand ist die Wahl des Menschen
|
|
48
|
+
(`model.effort`).
|
|
49
|
+
- **`strom grep`** durchsucht die Unterlagen, Notizen und Ausgaben der Forschung, auch über Akzente hinweg.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# What's new in Strom Research
|
|
2
|
+
|
|
3
|
+
English · [Čeština](CHANGELOG.cs.md) · [Deutsch](CHANGELOG.de.md)
|
|
4
|
+
|
|
5
|
+
The changes of each version in short. The full notes and the install lines are on
|
|
6
|
+
[GitHub Releases](https://github.com/ACiDekCZ/strom-research/releases).
|
|
7
|
+
|
|
8
|
+
## 1.15.0
|
|
9
|
+
|
|
10
|
+
*Goes with the Strom app 3.12.0.*
|
|
11
|
+
|
|
12
|
+
- **A Strom archive by choice, with an AI agent too.** The setup asks whether new family trees are researches with the
|
|
13
|
+
agent or only a Strom archive; the settings change it for one family tree or for the new ones.
|
|
14
|
+
- **A research waiting for its agent.** A family tree whose AI agent is not on this computer keeps what the Strom app
|
|
15
|
+
sends, as a Strom archive does. Once the agent is installed, the research goes on by itself.
|
|
16
|
+
- **One book of an archive, fetched once.** A book already in the research is named instead of being registered and
|
|
17
|
+
fetched again, so an archive is never asked twice for the same images.
|
|
18
|
+
- **Faster reading.** Five readers read the scans at the same time (the setting `read.parallel`, 1 to 10), and a long
|
|
19
|
+
download says how far it is ("40/109 images"). The readers begin while a book is still downloading: its images are
|
|
20
|
+
registered ten at a time, and what did not come is said exactly; Ctrl-C keeps what came. An archive gets the same
|
|
21
|
+
requests at the same pace. A book can also be fetched in the background while the agent works on (`strom fetch
|
|
22
|
+
--background`), never from an archive that allows only a person's pace. A search for one entry can stop at the find
|
|
23
|
+
(`strom read --until-found`): the images read are said exactly, and only they count as searched.
|
|
24
|
+
- **Family trees from other programs.** A GEDCOM file saved with a byte order mark or in UTF-16 (as some Windows
|
|
25
|
+
programs save it) is read as a family tree; a family tree of another research is taken in as a foreign one.
|
|
26
|
+
- **The live view ends cleanly** on every system, Windows too, and the Strom app learns that it ended.
|
|
27
|
+
- **One strom per installation.** Another strom on the same computer (from npm, or built from the sources) never takes
|
|
28
|
+
over the links of the Strom app or the update channel.
|
|
29
|
+
- **What's new.** After `strom update` and with `strom --version`, a link to this list in the research language. The
|
|
30
|
+
Strom app shows the points of a new research version in its own “What's new” window.
|
|
31
|
+
|
|
32
|
+
## 1.14.0
|
|
33
|
+
|
|
34
|
+
*2026-10-11 · goes with the Strom app 3.11.0.*
|
|
35
|
+
|
|
36
|
+
- **Each archive's terms.** strom keeps to how far each archive allows automated access: allowed, restricted, by hand
|
|
37
|
+
only, or not at all. Where the terms are unclear, the person decides once. A refusal pauses an archive for a day.
|
|
38
|
+
- **What waits, in places.** Things for the person are sorted by kind and grouped by where they are done: one archive,
|
|
39
|
+
one office, the family, one site. A letter or a question can be marked as sent.
|
|
40
|
+
- **Reading old handwriting.** Scans at the size each view needs, a reader of scans on the person's model, and the
|
|
41
|
+
reading tuned on the research's own proven records.
|
|
42
|
+
- **With the Strom app 3.11.0.** A conflict between an edit in the app and a record is decided in the app; hypotheses
|
|
43
|
+
show what each variant would connect.
|
|
44
|
+
- **A smaller brief that knows more**, and the reasoning effort is the person's choice (`model.effort`).
|
|
45
|
+
- **`strom grep`** searches the research's inputs, notes and output, through accents too.
|
package/README.md
CHANGED
|
@@ -48,7 +48,9 @@ Next time: run `strom`, or double-click the "Strom research" shortcut.
|
|
|
48
48
|
Updates: strom looks for a new version at most once a day and says so;
|
|
49
49
|
`strom update` installs it (checked like the installer does), and with it the
|
|
50
50
|
newest security release of its Node line. Installed with
|
|
51
|
-
npm: `npm install -g strom-research@latest`.
|
|
51
|
+
npm: `npm install -g strom-research@latest`. What is new in each version:
|
|
52
|
+
[CHANGELOG.md](CHANGELOG.md) ([čeština](CHANGELOG.cs.md), [Deutsch](CHANGELOG.de.md));
|
|
53
|
+
`strom --version` and `strom update` link to it in the research language.
|
|
52
54
|
|
|
53
55
|
## Features
|
|
54
56
|
|
package/assets/lang/cs.json
CHANGED
|
@@ -250,6 +250,7 @@
|
|
|
250
250
|
"ui.tune.book.weak": "zápory na slabých skenech {n} z {of}",
|
|
251
251
|
"ui.tune.book.requests": "požadavky {n}",
|
|
252
252
|
"ui.tune.book.unread": "staženo a nepřečteno {n} z {of}",
|
|
253
|
+
"ui.tune.book.background": "na pozadí: nepřečteno {n} z {of}",
|
|
253
254
|
"ui.tune.hosts": "Archivy:",
|
|
254
255
|
"ui.tune.host": " {host}: sezení {sessions} · požadavky {requests} ({perSession} na sezení, {perImage} na snímek) · čekání {wait} min · limit vyčerpán {later}×",
|
|
255
256
|
"ui.tune.web": "Webové nástroje agenta:",
|
|
@@ -754,6 +755,7 @@
|
|
|
754
755
|
"ui.update.downloading": "Stahuji strom {version}…",
|
|
755
756
|
"ui.update.failed": "Aktualizace se nepovedla: {detail}. strom zůstává, jak byl.",
|
|
756
757
|
"ui.update.done": "✓ strom je aktualizovaný: {previous} → {version}.",
|
|
758
|
+
"ui.update.whatsnew": "Co je nového: {url}",
|
|
757
759
|
"ui.update.restart": "strom je aktualizovaný — tahle nabídka ale ještě běží ve staré verzi. Po novém spuštění stromu (nebo zástupce „{shortcut}“) poběží nová verze.",
|
|
758
760
|
"ui.o.update": "aktualizace",
|
|
759
761
|
"ui.o.update.new": "vyšla {version} (tato je {current}) – řekni to uživateli; strom update ji s jeho souhlasem nainstaluje",
|
package/assets/lang/de.json
CHANGED
|
@@ -250,6 +250,7 @@
|
|
|
250
250
|
"ui.tune.book.weak": "Negativbefunde auf schwachen Scans {n} von {of}",
|
|
251
251
|
"ui.tune.book.requests": "Anfragen {n}",
|
|
252
252
|
"ui.tune.book.unread": "geladen und nie gelesen {n} von {of}",
|
|
253
|
+
"ui.tune.book.background": "im Hintergrund: nie gelesen {n} von {of}",
|
|
253
254
|
"ui.tune.hosts": "Archive:",
|
|
254
255
|
"ui.tune.host": " {host}: Sitzungen {sessions} · Anfragen {requests} ({perSession} pro Sitzung, {perImage} pro Bild) · gewartet {wait} min · Limit erschöpft {later}×",
|
|
255
256
|
"ui.tune.web": "Eigene Webwerkzeuge des Agenten:",
|
|
@@ -754,6 +755,7 @@
|
|
|
754
755
|
"ui.update.downloading": "strom {version} wird heruntergeladen…",
|
|
755
756
|
"ui.update.failed": "Die Aktualisierung hat nicht geklappt: {detail}. strom bleibt, wie er war.",
|
|
756
757
|
"ui.update.done": "✓ strom ist aktualisiert: {previous} → {version}.",
|
|
758
|
+
"ui.update.whatsnew": "Was ist neu: {url}",
|
|
757
759
|
"ui.update.restart": "strom ist aktualisiert — dieses Menü läuft aber noch in der alten Version. Nach einem Neustart von strom (oder der Verknüpfung „{shortcut}“) läuft die neue Version.",
|
|
758
760
|
"ui.o.update": "Update",
|
|
759
761
|
"ui.o.update.new": "{version} ist da (diese ist {current}) – sag es dem Benutzer; strom update installiert sie mit seiner Zustimmung",
|
package/assets/method/core.md
CHANGED
|
@@ -102,6 +102,9 @@ conclusion so the next researcher can follow it.
|
|
|
102
102
|
number by one or two images, never a batch of ten; an entry: its image ±1
|
|
103
103
|
(it may run over a page). An archive that allows automation: batches as
|
|
104
104
|
usual (about ±5 around the target, an index in batches) — fewer turns.
|
|
105
|
+
`strom read` may follow a fetch at work: sooner, never more images.
|
|
106
|
+
Images you will read later in the session: `--background` fetches them
|
|
107
|
+
while you work on, `strom read` reads them as they come.
|
|
105
108
|
<!-- end -->
|
|
106
109
|
- **What strom or the tree denies stays denied.** Never offer the user to
|
|
107
110
|
change your permissions or settings, strom's or the tree's, to get round it:
|
package/assets/method/reading.md
CHANGED
|
@@ -65,6 +65,13 @@ never open again a view cleared from your context — your notes hold it.
|
|
|
65
65
|
and headings only, one surname's entries, one entry whole — and transcribes
|
|
66
66
|
nothing else. Record each report as it comes back, before the next readers.
|
|
67
67
|
Only the entries that will be cited need your own eyes, at full resolution.
|
|
68
|
+
<!-- for link verify enrich -->
|
|
69
|
+
- **`--until-found` only for ONE particular entry** (one person's baptism,
|
|
70
|
+
marriage or burial whose details you know): no more readers begin once one
|
|
71
|
+
reports it. Never for every entry of a place or surname, nor where a
|
|
72
|
+
namesake may follow. Record only the images it names as read, `--result
|
|
73
|
+
partial`; if the find is not the one, read the rest.
|
|
74
|
+
<!-- end -->
|
|
68
75
|
- **Report image by image, as you go**: the image and page, what was found (or
|
|
69
76
|
nothing), what was illegible and where, the hand, how sure each name is.
|
|
70
77
|
- **Cite the image, and where the entry is on it**: `strom source add …
|
package/dist/brief/brief.js
CHANGED
|
@@ -39,6 +39,7 @@ import { ENRICH_PAGES, STORY_SOURCES_ORIGIN } from "../core/stories.js";
|
|
|
39
39
|
import { sandboxOf, WITHOUT_READERS } from "../core/sandbox.js";
|
|
40
40
|
import { WEB_SOFT } from "../core/metrics.js";
|
|
41
41
|
import { indexBriefLines } from "../core/indexfirst.js";
|
|
42
|
+
import { activeFetches, endedFetches } from "../core/fetching.js";
|
|
42
43
|
/** The hosts of a connector, as its manifest names them (a wildcard without its star). */
|
|
43
44
|
function connectorHosts(shared, name) {
|
|
44
45
|
try {
|
|
@@ -627,6 +628,15 @@ function imagesLines(tree, b, route, shape, finder, noSharper = false, waiting)
|
|
|
627
628
|
: ""),
|
|
628
629
|
].filter(Boolean);
|
|
629
630
|
}
|
|
631
|
+
/** The fetches at work for the research (each book: how far), and those in the background that ended lately with images left. */
|
|
632
|
+
function fetchingLines(root) {
|
|
633
|
+
const active = activeFetches(root);
|
|
634
|
+
const out = active.map((m) => `- ${m.recordset}: ${m.registered}/${m.images.length} images registered (${m.background ? `in the background${m.task ? `, for ${m.task}` : ""}` : "in the foreground"}) — strom read ${m.recordset} --images ${runs(m.images)} reads them as they come; not fetched again`);
|
|
635
|
+
for (const e of endedFetches(root))
|
|
636
|
+
if (e.missed.length && !active.some((m) => m.recordset === e.recordset))
|
|
637
|
+
out.push(`- ${e.recordset}: a fetch in the background ended with images ${runs(e.missed)} not fetched${e.stopped ? ` (stopped: ${e.stopped})` : ""} — strom fetch ${e.connector} ${shellArg(e.book)} --images ${runs(e.missed)} --recordset ${e.recordset} if they are needed`);
|
|
638
|
+
return out;
|
|
639
|
+
}
|
|
630
640
|
/** What the user put in the shared inbox, waiting to be registered — by folder (one download each). */
|
|
631
641
|
function inboxLines(shared) {
|
|
632
642
|
if (!shared)
|
|
@@ -1197,6 +1207,15 @@ export function buildBrief(tree, opts) {
|
|
|
1197
1207
|
' strom media add --inbox "<folder>" --recordset B… · a document (certificate, letter): strom intake <file>',
|
|
1198
1208
|
].join("\n"),
|
|
1199
1209
|
});
|
|
1210
|
+
// 7c. images being fetched for the research now (strom fetch --background of an earlier session, or another strom),
|
|
1211
|
+
// and what fetches in the background left unfetched lately: read as they come, never fetched twice
|
|
1212
|
+
const fetching = fetchingLines(tree.root);
|
|
1213
|
+
if (fetching.length)
|
|
1214
|
+
sections.push({
|
|
1215
|
+
name: "fetching",
|
|
1216
|
+
pointer: "strom fetch --status",
|
|
1217
|
+
text: ["## Images being fetched now (strom fetch --status)", ...fetching].join("\n"),
|
|
1218
|
+
});
|
|
1200
1219
|
// 8. method for this kind of task
|
|
1201
1220
|
// (budgeted first, with the record sets and the commands: when the brief is long, the lists are cut before how to work)
|
|
1202
1221
|
// only the parts the level uses — of getting images, those of how this task's record sets get them (none named:
|
package/dist/brief/sheet.js
CHANGED
|
@@ -29,8 +29,8 @@ const RARE = {
|
|
|
29
29
|
"task add": ["research", "anyway"],
|
|
30
30
|
"media view": ["scale", "max", "grey", "png", "image"],
|
|
31
31
|
read: ["context", "batch", "model", "minutes", "max"],
|
|
32
|
-
// a book the research has already: the refusal says --again where it applies
|
|
33
|
-
fetch: ["take", "result", "again"],
|
|
32
|
+
// a book the research has already: the refusal says --again where it applies; --status and --stop: the method and the brief name them
|
|
33
|
+
fetch: ["take", "result", "again", "status", "stop"],
|
|
34
34
|
"source add": ["translation", "media"],
|
|
35
35
|
"source edit": ["translation", "media"],
|
|
36
36
|
"recordset add": ["images", "again"],
|
package/dist/cli/commit.js
CHANGED
|
@@ -13,7 +13,9 @@ export function commitMessage(summaries, command) {
|
|
|
13
13
|
/** Commit the changes of this command. Returns what blocked the commit, if anything did. */
|
|
14
14
|
export function autoCommit(ctx, def) {
|
|
15
15
|
const tree = ctx.current();
|
|
16
|
-
|
|
16
|
+
// what an earlier commit of the same command holds already (strom fetch commits each batch of images) is not again
|
|
17
|
+
const ops = tree?.uncommitted() ?? [];
|
|
18
|
+
if (!tree || tree.dryRun || ops.length === 0)
|
|
17
19
|
return undefined;
|
|
18
20
|
// Incremental gate: records were validated when written; here only what
|
|
19
21
|
// changed since the last commit is checked, so the cost stays flat.
|
|
@@ -30,11 +32,11 @@ export function autoCommit(ctx, def) {
|
|
|
30
32
|
problems: errors.map((f) => ({ ...(f.id ? { id: f.id } : {}), ...(f.file ? { file: f.file } : {}), message: f.message })),
|
|
31
33
|
};
|
|
32
34
|
}
|
|
33
|
-
const message = commitMessage(
|
|
35
|
+
const message = commitMessage(ops.map((o) => o.summary), `strom ${def.path.join(" ")}`);
|
|
34
36
|
// Only the files this command wrote, plus the free-form folders the agent
|
|
35
37
|
// may edit — `git add` then never has to scan the whole data/ tree.
|
|
36
38
|
const written = new Set(["data/_counters.json"]);
|
|
37
|
-
for (const op of
|
|
39
|
+
for (const op of ops)
|
|
38
40
|
for (const f of op.files)
|
|
39
41
|
written.add(f.path);
|
|
40
42
|
for (const f of tree.opsFilesTouched())
|
|
@@ -43,6 +45,7 @@ export function autoCommit(ctx, def) {
|
|
|
43
45
|
// commit of something else (found on Windows: strom mode committed a file of the user's) — nor by the switch itself
|
|
44
46
|
const free = isArchive(tree) || def.path[0] === "mode" ? ["inputs", "output"] : ["notes", "tools", "inputs", "output"];
|
|
45
47
|
tree.withTreeLock(() => tree.commit(message, [...written, ...free]));
|
|
48
|
+
tree.markCommitted();
|
|
46
49
|
tree.settle();
|
|
47
50
|
return undefined;
|
|
48
51
|
}
|
package/dist/cli/execute.js
CHANGED
|
@@ -346,9 +346,9 @@ export function severalRecords(def, args) {
|
|
|
346
346
|
return RECORD_SHOWS.has(def.path.join(" ")) && args.length > 1 && args.every(isRecordRef);
|
|
347
347
|
}
|
|
348
348
|
/** Required and surplus positional arguments; `fix`: the line as it is meant (parseOptions), said under a surplus one. */
|
|
349
|
-
export function checkArgs(def, args, fix, program = "strom") {
|
|
349
|
+
export function checkArgs(def, args, fix, program = "strom", opts = {}) {
|
|
350
350
|
const declared = def.args ?? [];
|
|
351
|
-
const required = declared.filter((a) => a.required);
|
|
351
|
+
const required = declared.filter((a) => a.required && !a.unless?.some((o) => opts[o] !== undefined && opts[o] !== false));
|
|
352
352
|
if (args.length < required.length) {
|
|
353
353
|
const missing = required[args.length];
|
|
354
354
|
throw new UsageError(`missing <${missing.name}>: ${missing.description}`, { hint: `strom help ${def.path.join(" ")}`, code: "arg.missing", params: { arg: missing.name, cmd: def.path.join(" ") }, usage: usageOf(def) });
|
package/dist/cli/main.js
CHANGED
|
@@ -23,7 +23,7 @@ import { prependPath } from "../runners/runner.js";
|
|
|
23
23
|
import { shimDir } from "../commands/session.js";
|
|
24
24
|
import { isAgent } from "../core/which.js";
|
|
25
25
|
import { appUrlShown, noticeStromApp } from "../core/stromapp.js";
|
|
26
|
-
import { lastChannelOf, pendingTransition, updateChannel } from "../core/update.js";
|
|
26
|
+
import { lastChannelOf, pendingTransition, updateChannel, whatsNewUrl } from "../core/update.js";
|
|
27
27
|
import { backupBefore, backupSaid } from "./backups.js";
|
|
28
28
|
import { guestOf, installation, ownFolder, refreshTreeShim } from "../core/self.js";
|
|
29
29
|
import { refreshGlobal } from "../agents/global.js";
|
|
@@ -133,6 +133,21 @@ function asOwnCommand(io, name, json, argv) {
|
|
|
133
133
|
const text = (s) => asCommand(s, name, words);
|
|
134
134
|
return { ...io, stdout: (s) => io.stdout(json ? asCommandJson(s, name, words) : text(s)), stderr: (s) => io.stderr(text(s)) };
|
|
135
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* strom --version: the version on its first line (what a script reads), then where to read what is new in it — the
|
|
138
|
+
* changelog in the research language, on the branch of the installation's channel. --json gives the version alone.
|
|
139
|
+
*/
|
|
140
|
+
function versionSaid(env, cwd, io, values = {}) {
|
|
141
|
+
const first = `strom ${VERSION}\n`;
|
|
142
|
+
try {
|
|
143
|
+
const lang = Context.fromOptions({ env, cwd, io, json: false, values }).uiLang();
|
|
144
|
+
return `${first}${ui(lang, "ui.update.whatsnew", { url: whatsNewUrl(VERSION, updateChannel(env), lang) })}\n`;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// no settings to read: the version alone
|
|
148
|
+
return first;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
136
151
|
export async function main(argv, io, env, cwd) {
|
|
137
152
|
const json = argv.includes("--json");
|
|
138
153
|
const own = ownCommand(env);
|
|
@@ -157,7 +172,7 @@ export async function main(argv, io, env, cwd) {
|
|
|
157
172
|
if (argv.length === 0 && io.tty && !isAgent(env) && env.STROM_NONINTERACTIVE !== "1")
|
|
158
173
|
argv = ["menu"];
|
|
159
174
|
if (argv.length === 1 && (argv[0] === "--version" || argv[0] === "-v")) {
|
|
160
|
-
io.stdout(json ? toJson({ version: VERSION }) :
|
|
175
|
+
io.stdout(json ? toJson({ version: VERSION }) : versionSaid(env, cwd, io));
|
|
161
176
|
return EXIT.ok;
|
|
162
177
|
}
|
|
163
178
|
let resolved;
|
|
@@ -185,7 +200,7 @@ export async function main(argv, io, env, cwd) {
|
|
|
185
200
|
return EXIT.ok;
|
|
186
201
|
}
|
|
187
202
|
if (v.version) {
|
|
188
|
-
io.stdout(json ? toJson({ version: VERSION }) :
|
|
203
|
+
io.stdout(json ? toJson({ version: VERSION }) : versionSaid(env, cwd, io, v));
|
|
189
204
|
return EXIT.ok;
|
|
190
205
|
}
|
|
191
206
|
const ctx = Context.fromOptions({ env, cwd, io, json, values: v });
|
|
@@ -337,13 +352,14 @@ export async function main(argv, io, env, cwd) {
|
|
|
337
352
|
// several IDs to a show command of one record (person show P0001 P0002): each shown in turn, as strom show does
|
|
338
353
|
const shows = severalRecords(def, args) ? match(["show"])?.def : undefined;
|
|
339
354
|
if (!shows)
|
|
340
|
-
checkArgs(def, args, parsed.fix, own);
|
|
355
|
+
checkArgs(def, args, parsed.fix, own, parsed.values);
|
|
341
356
|
if (def.writes && v["dry-run"])
|
|
342
357
|
ctx.dryRun = true;
|
|
343
358
|
const work = async () => {
|
|
344
359
|
// Never write on top of data that was changed outside strom.
|
|
360
|
+
// (a command that locks only while it writes looks under the lock too: another strom may be in the middle of a write)
|
|
345
361
|
if (def.writes && def.tree)
|
|
346
|
-
assertIntact(ctx.tree());
|
|
362
|
+
def.lock === "sections" ? ctx.tree().withTreeLock(() => assertIntact(ctx.tree())) : assertIntact(ctx.tree());
|
|
347
363
|
let result;
|
|
348
364
|
try {
|
|
349
365
|
result = await (shows ?? def).run(ctx, { args, opts: v, ...(passthrough.length ? { extra: passthrough } : {}), ...(parsed.seq ? { seq: parsed.seq } : {}) });
|
package/dist/cli/ui.js
CHANGED
|
@@ -227,6 +227,7 @@ export const UI = {
|
|
|
227
227
|
"ui.tune.book.weak": "negatives on weak scans {n} of {of}",
|
|
228
228
|
"ui.tune.book.requests": "requests {n}",
|
|
229
229
|
"ui.tune.book.unread": "fetched and never read {n} of {of}",
|
|
230
|
+
"ui.tune.book.background": "in the background: never read {n} of {of}",
|
|
230
231
|
"ui.tune.hosts": "Archives:",
|
|
231
232
|
"ui.tune.host": " {host}: sessions {sessions} · requests {requests} ({perSession} per session, {perImage} per image) · waited {wait} min · limit used up {later}×",
|
|
232
233
|
"ui.tune.web": "The agent's own web tools:",
|
|
@@ -681,6 +682,7 @@ export const UI = {
|
|
|
681
682
|
"ui.update.downloading": "Downloading strom {version}…",
|
|
682
683
|
"ui.update.failed": "The update did not work: {detail}. strom stays as it was.",
|
|
683
684
|
"ui.update.done": "✓ strom is updated: {previous} → {version}.",
|
|
685
|
+
"ui.update.whatsnew": "What's new: {url}",
|
|
684
686
|
"ui.update.restart": "strom is updated — this menu still runs the old version. Start strom again (or the shortcut \"{shortcut}\"), and the new version is at work.",
|
|
685
687
|
"ui.o.update": "update",
|
|
686
688
|
"ui.o.update.new": "{version} is out (this is {current}) — tell the user; strom update installs it with their yes",
|
package/dist/commands/batch.js
CHANGED
|
@@ -217,7 +217,7 @@ register({
|
|
|
217
217
|
// one line cannot be a dry run while the others write: the whole batch is one or neither
|
|
218
218
|
if (parsed.values["dry-run"])
|
|
219
219
|
throw new UsageError("--dry-run applies to the whole batch: strom batch --dry-run …");
|
|
220
|
-
checkArgs(def, parsed.positionals, parsed.fix, "");
|
|
220
|
+
checkArgs(def, parsed.positionals, parsed.fix, "", parsed.values);
|
|
221
221
|
const before = tree.written.length;
|
|
222
222
|
const r = await def.run(ctx, { args: parsed.positionals, opts: parsed.values });
|
|
223
223
|
if (r.exitCode)
|
|
@@ -164,6 +164,7 @@ function report(ctx, tree, askedKey, whoAsked) {
|
|
|
164
164
|
b.weakNegatives ? t("ui.tune.book.weak", { n: b.weakNegatives, of: b.negatives }) : undefined,
|
|
165
165
|
b.requests ? t("ui.tune.book.requests", { n: b.requests }) : undefined,
|
|
166
166
|
b.unread ? t("ui.tune.book.unread", { n: b.unread, of: b.fetched }) : undefined,
|
|
167
|
+
b.background ? t("ui.tune.book.background", { n: b.background.unread, of: b.background.fetched }) : undefined,
|
|
167
168
|
]
|
|
168
169
|
.filter(Boolean)
|
|
169
170
|
.join(" · "));
|