strom-research 1.19.0-beta.7 → 1.19.0-beta.8
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 -4
- package/CHANGELOG.de.md +23 -6
- package/CHANGELOG.md +21 -7
- package/README.md +4 -1
- package/assets/lang/cs.json +34 -1
- package/assets/lang/de.json +34 -1
- package/dist/agents/files.js +42 -7
- package/dist/agents/global.js +3 -1
- package/dist/agents/launch.js +3 -1
- package/dist/cli/backups.js +21 -2
- package/dist/cli/main.js +40 -9
- package/dist/cli/registry.js +3 -0
- package/dist/cli/ui.js +34 -1
- package/dist/commands/checks.js +31 -4
- package/dist/commands/connectors.js +3 -0
- package/dist/commands/session.js +2 -0
- package/dist/commands/setup.js +20 -1
- package/dist/commands/start.js +1 -1
- package/dist/commands/trees.js +60 -11
- package/dist/core/backup.js +6 -2
- package/dist/core/git.js +16 -2
- package/dist/core/lock.js +177 -9
- package/dist/core/shortcut.js +1 -1
- package/dist/core/tree.js +1 -1
- package/dist/core/trust.js +19 -5
- package/dist/core/which.js +5 -1
- package/dist/core/writable.js +153 -0
- package/package.json +1 -1
package/CHANGELOG.cs.md
CHANGED
|
@@ -7,7 +7,7 @@ Změny každé verze ve zkratce. Úplné poznámky a instalační řádky jsou n
|
|
|
7
7
|
|
|
8
8
|
## 1.19.0
|
|
9
9
|
|
|
10
|
-
*Připravuje se: bety do 1.19.0-beta.
|
|
10
|
+
*Připravuje se: bety do 1.19.0-beta.8. Oddíl bude úplný s vydáním.*
|
|
11
11
|
|
|
12
12
|
- **Na archiv, který zmlkl, se čeká, místo opakovaných dotazů.** Když archiv přestane odpovídat, strom ho nechá na
|
|
13
13
|
pokoji hodinu — a když týž den mlčí dál, dvě a pak čtyři hodiny — a agent se dozví, do kdy: mezitím dělá
|
|
@@ -16,7 +16,8 @@ Změny každé verze ve zkratce. Úplné poznámky a instalační řádky jsou n
|
|
|
16
16
|
- **První úklid staršího výzkumu se jednou nabídne.** Výzkum, u kterého se nastřádalo hodně dat dřív, než si v tom
|
|
17
17
|
strom začal sám dělat pořádek (záznamy práce, náhledy snímků a podobně), dostane v menu jednu nabídku: co by se
|
|
18
18
|
smazalo, kolik a proč — bez souhlasu nic. Po souhlasu se v tom pak udržuje pořádek samo; po odmítnutí menu a
|
|
19
|
-
nastavení dál říkají, co jde uvolnit.
|
|
19
|
+
nastavení dál říkají, co jde uvolnit. `strom pack`, odebrání rodokmenu i menu uvádějí velikost balíku, zálohy nebo
|
|
20
|
+
snímků jako všude jinde (1,5 MB, u malých 24 kB), nikdy „0.0 MB“.
|
|
20
21
|
- **Digitální knihovny napoprvé správně.** U Krameria Národní knihovny ČR a Moravské zemské knihovny a u ANNO
|
|
21
22
|
Rakouské národní knihovny dostane agent jejich vlastní vyhledávací adresy — méně neúspěšných dotazů a hádání.
|
|
22
23
|
- **Ostřejší část snímku se opravdu čte.** Když z archivu přišla část snímku v lepším rozlišení, agent i jeho čtenáři
|
|
@@ -43,8 +44,21 @@ Změny každé verze ve zkratce. Úplné poznámky a instalační řádky jsou n
|
|
|
43
44
|
agent nebo model (`strom fixes run <id> --agent <a> --model <m>`), s tím, kdo četl dřív; ten, kdo tu číst nemůže, se
|
|
44
45
|
odmítne hned i s těmi, kdo mohou. Čas napravení se zaokrouhluje nahoru a po zkoušce se přepočítá podle čtení, jak
|
|
45
46
|
běžela souběžně.
|
|
46
|
-
- **
|
|
47
|
-
|
|
47
|
+
- **Rodokmen, do kterého strom nesmí zapisovat, řekne proč.** strom zapíše do složky výzkumu pravidla pro Codex:
|
|
48
|
+
příkaz strom spuštěný samotný jde mimo sandbox Codexu — i na Windows, kde sandbox držel historii výzkumu zavřenou
|
|
49
|
+
a nic jiného nepustil — a co rozhoduje člověk a samotný git zůstává zakázané. Když zápisu do složky rodokmenu
|
|
50
|
+
sandbox agenta přesto brání, strom to řekne a agentovi poradí, co dělat podle toho, jak běží — spouštět strom
|
|
51
|
+
samotný, spustit Codex ve složce výzkumu, které důvěřuje, nebo nechat příkaz schválit mimo sandbox — místo holého
|
|
52
|
+
„chybí oprávnění“, které agent převyprávěl jako „nemám přístup k rodokmenu“. Kde agent nenechá žádnou svou značku,
|
|
53
|
+
pozná ho strom podle vlastní značky u agentů, které spouští, nebo podle programů, které ho spustily, a jako
|
|
54
|
+
pravděpodobnou příčinu jmenuje jeho sandbox, potom OneDrive nebo řízený přístup ke složkám ve Windows. Odmítnutý
|
|
55
|
+
zápis do historie se už nehlásí jako chybějící oprávnění k samotnému gitu a záloha nebo aktualizace, kterou nešlo
|
|
56
|
+
zapsat, žádá složku, do které lze zapisovat, a už neradí uvolnit místo na disku. `strom doctor` a `strom check`
|
|
57
|
+
zápis do výzkumu zkusí a řeknou, když nejde, i tam, kde složku nejde ani vypsat. Na disku bez pevných odkazů
|
|
58
|
+
(síťové úložiště, disk přesměrovaný přes Vzdálenou plochu) strom zase zapisuje, zámek jde jinou cestou, a zámek,
|
|
59
|
+
který pomalý disk ještě neukáže, už se po chvilce nepřebírá; rodokmen, který tam nejde založit, po sobě nic nenechá
|
|
60
|
+
a řekne to v jazyce výzkumu. Po instalaci přes npm na Windows spustí strom příkaz `strom.cmd` i tam, kde PowerShell
|
|
61
|
+
skripty odmítá.
|
|
48
62
|
|
|
49
63
|
## 1.18.0
|
|
50
64
|
|
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.19.0
|
|
9
9
|
|
|
10
|
-
*In Vorbereitung: die Betas bis 1.19.0-beta.
|
|
10
|
+
*In Vorbereitung: die Betas bis 1.19.0-beta.8. Der Abschnitt ist mit dem Release vollständig.*
|
|
11
11
|
|
|
12
12
|
- **Auf ein verstummtes Archiv wird gewartet, statt es immer wieder zu fragen.** Antwortet ein Archiv nicht mehr,
|
|
13
13
|
lässt strom es eine Stunde in Ruhe — zwei, dann vier, wenn es am selben Tag still bleibt — und der Agent erfährt, bis
|
|
@@ -16,8 +16,10 @@ Die Änderungen jeder Version in Kürze. Die vollständigen Hinweise und die Ins
|
|
|
16
16
|
immer wieder angefragt.
|
|
17
17
|
- **Das erste Aufräumen einer älteren Forschung wird einmal angeboten.** Eine Forschung, neben der sich viel
|
|
18
18
|
angesammelt hat, bevor strom dort selbst Ordnung hielt (Protokolle der Arbeitssitzungen, Ansichten von Scans und
|
|
19
|
-
Ähnliches), bekommt im Menü ein Angebot: was ginge, wie viel und warum — ohne Ja geht nichts. Nach einem Ja wird
|
|
20
|
-
von selbst Ordnung gehalten; nach einem Nein sagen Menü und Einstellungen weiter, was sich freigeben lässt.
|
|
19
|
+
Ähnliches), bekommt im Menü ein Angebot: was ginge, wie viel und warum — ohne Ja geht nichts. Nach einem Ja wird
|
|
20
|
+
dort von selbst Ordnung gehalten; nach einem Nein sagen Menü und Einstellungen weiter, was sich freigeben lässt.
|
|
21
|
+
`strom pack`, das Entfernen eines Stammbaums und das Menü nennen die Größe eines Pakets, einer Sicherung oder der
|
|
22
|
+
Bilder wie überall sonst (1,5 MB, bei kleinen 24 kB), nie „0.0 MB“.
|
|
21
23
|
- **Digitale Bibliotheken beim ersten Versuch richtig durchsucht.** Für Kramerius der Tschechischen
|
|
22
24
|
Nationalbibliothek und der Mährischen Landesbibliothek und für ANNO der Österreichischen Nationalbibliothek bekommt
|
|
23
25
|
der Agent die eigenen Suchadressen der Bibliotheken — weniger fehlgeschlagene Anfragen und weniger Raten.
|
|
@@ -50,9 +52,24 @@ Die Änderungen jeder Version in Kürze. Die vollständigen Hinweise und die Ins
|
|
|
50
52
|
bereiter Agent oder ein anderes Modell (`strom fixes run <id> --agent <a> --model <m>`), mit dem, der vorher las;
|
|
51
53
|
einer, der hier nicht lesen kann, wird sofort abgelehnt, mit denen, die es können. Die Zeit einer Behebung wird
|
|
52
54
|
aufgerundet und nach dem Versuch nach den nebeneinander gelaufenen Lesungen neu gemessen.
|
|
53
|
-
- **
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
- **Ein Stammbaum, in den strom nicht schreiben darf, sagt warum.** strom schreibt Regeln für Codex in den Ordner der
|
|
56
|
+
Forschung: ein allein ausgeführter strom-Befehl läuft außerhalb der Sandbox von Codex — auch unter Windows, wo die
|
|
57
|
+
Sandbox den Verlauf der Forschung verschlossen hielt und nichts anderes zuließ —, während das, was der Mensch
|
|
58
|
+
entscheidet, und git selbst verboten bleiben. Hindert die Sandbox eines Agenten strom trotzdem am Schreiben in den
|
|
59
|
+
Ordner des Stammbaums, sagt strom das und sagt dem Agenten, was zu tun ist, je nachdem, wie er läuft — strom allein
|
|
60
|
+
ausführen, Codex im Ordner der Forschung starten, dem er vertraut, oder den Befehl außerhalb der Sandbox genehmigen
|
|
61
|
+
lassen — statt eines bloßen „keine Berechtigung“, das der Agent als fehlenden Zugriff auf den Stammbaum wiedergab.
|
|
62
|
+
Wo ein Agent kein eigenes Merkmal hinterlässt, erkennt strom ihn an seinem eigenen Merkmal bei den Agenten, die es
|
|
63
|
+
startet, oder an den Programmen, die es gestartet haben, und nennt seine Sandbox als wahrscheinliche Ursache, danach
|
|
64
|
+
OneDrive oder den überwachten Ordnerzugriff von Windows. Ein vom Verlauf verweigertes Schreiben gilt nicht mehr als
|
|
65
|
+
fehlende Berechtigung für git selbst, und eine Sicherung oder ein Update, die nicht geschrieben werden konnten,
|
|
66
|
+
verlangen einen Ordner, in den geschrieben werden darf, statt Platz auf dem Datenträger freizumachen. `strom doctor`
|
|
67
|
+
und `strom check` versuchen, in die Forschung zu schreiben, und sagen, wenn es nicht geht, auch dort, wo sich der
|
|
68
|
+
Ordner nicht einmal auflisten lässt. Auf einem Laufwerk ohne feste Verknüpfungen (eine Netzwerkfreigabe, ein über
|
|
69
|
+
Remotedesktop umgeleitetes Laufwerk) schreibt strom wieder, seine Sperre geht einen anderen Weg, und eine Sperre, die
|
|
70
|
+
ein langsames Laufwerk noch nicht zeigt, wird nicht mehr nach einem Augenblick übernommen; ein Stammbaum, der sich
|
|
71
|
+
dort nicht anlegen lässt, hinterlässt nichts und sagt es in der Sprache der Forschung. Mit npm unter Windows
|
|
72
|
+
installiert, startet `strom.cmd` strom auch dort, wo PowerShell Skripte verweigert.
|
|
56
73
|
|
|
57
74
|
## 1.18.0
|
|
58
75
|
|
package/CHANGELOG.md
CHANGED
|
@@ -7,16 +7,17 @@ The changes of each version in short. The full notes and the install lines are o
|
|
|
7
7
|
|
|
8
8
|
## 1.19.0
|
|
9
9
|
|
|
10
|
-
*In preparation: the betas up to 1.19.0-beta.
|
|
10
|
+
*In preparation: the betas up to 1.19.0-beta.8. The section is complete with the release.*
|
|
11
11
|
|
|
12
12
|
- **An archive that went silent is waited for, not asked again and again.** When an archive stops answering, strom
|
|
13
13
|
leaves it alone for an hour — two, then four when it stays silent the same day — and the agent hears until when:
|
|
14
14
|
it goes on with other work, lets a download in the background wait for the archive (up to 30 minutes) and go on by
|
|
15
15
|
itself, or closes the session to go on later. No more asking the archive over and over meanwhile.
|
|
16
|
-
- **The first tidy of an older research is offered once.** A research that gathered much beside it before strom
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
- **The first tidy of an older research is offered once.** A research that gathered much beside it before strom kept
|
|
17
|
+
order there by itself (logs of work sessions, views of scans and the like) gets one offer in the menu: what would
|
|
18
|
+
go, how much and why, and nothing goes without a yes. After a yes it is kept in order by itself; after a no, the
|
|
19
|
+
menu and the settings keep saying what can be freed. `strom pack`, removing a family tree and the menu say how big a
|
|
20
|
+
package, a backup or the images are as everywhere else (1,5 MB in Czech, 24 kB for a small one), never "0.0 MB".
|
|
20
21
|
- **Digital libraries searched right at the first try.** For Kramerius of the Czech National Library and of the
|
|
21
22
|
Moravian Library and for ANNO of the Austrian National Library, the agent gets the libraries' own search
|
|
22
23
|
addresses — fewer failed requests and less guessing.
|
|
@@ -46,8 +47,21 @@ The changes of each version in short. The full notes and the install lines are o
|
|
|
46
47
|
ordering them. The remedy may be read by another agent or model ready here (`strom fixes run <id> --agent <a>
|
|
47
48
|
--model <m>`), with which one read before said; one that cannot read here is refused at once, with those that can.
|
|
48
49
|
The time of a remedy is rounded up and, after the trial, measured again by the readings as they ran side by side.
|
|
49
|
-
- **
|
|
50
|
-
|
|
50
|
+
- **A family tree strom may not write into says why.** strom writes Codex's rules into the research's folder: a strom
|
|
51
|
+
command run on its own goes outside Codex's sandbox — on Windows too, where the sandbox kept the research's history
|
|
52
|
+
closed and let nothing else run — while what the person decides and git itself stay forbidden. When an agent's
|
|
53
|
+
sandbox still keeps strom from writing into the family tree's folder, strom says so and tells the agent what to do as
|
|
54
|
+
it is there — run strom on its own, start Codex in the research's folder it trusts, or have the command approved
|
|
55
|
+
outside the sandbox — instead of a bare "no permission" the agent retold as no access to the family tree. Where an
|
|
56
|
+
agent leaves no mark of its own, strom knows it by its own mark on the agents it starts, or by the programs that
|
|
57
|
+
started it, and names its sandbox as the likely cause, then OneDrive or the controlled folder access of Windows. A
|
|
58
|
+
write the history refused is no longer said as missing rights to git itself, and a backup or an update that could not
|
|
59
|
+
be written asks for a folder with the right to write in it, no longer to free room on the disk. `strom doctor` and
|
|
60
|
+
`strom check` try writing into the research and say when it does not go, also where the folder cannot even be
|
|
61
|
+
listed. On a disk without hard links (a network share, a drive redirected over Remote Desktop) strom writes again,
|
|
62
|
+
its lock made another way, and a lock a slow disk does not show yet is no longer taken over after a moment; a family
|
|
63
|
+
tree that cannot be created there leaves nothing behind, said in the research language. Installed with npm on
|
|
64
|
+
Windows, `strom.cmd` runs strom where PowerShell refuses scripts.
|
|
51
65
|
|
|
52
66
|
## 1.18.0
|
|
53
67
|
|
package/README.md
CHANGED
|
@@ -34,7 +34,10 @@ Nothing needs admin rights.
|
|
|
34
34
|
- **macOS, Linux**:
|
|
35
35
|
`curl -fsSL https://raw.githubusercontent.com/ACiDekCZ/strom-research/main/install/install.sh | sh`
|
|
36
36
|
|
|
37
|
-
With Node 22.18 or newer: `npm install -g strom-research`.
|
|
37
|
+
With Node 22.18 or newer: `npm install -g strom-research`. On Windows the
|
|
38
|
+
installer above is the recommended way: installed with npm, PowerShell may
|
|
39
|
+
refuse `strom` ("running scripts is disabled on this system") — `strom.cmd`
|
|
40
|
+
runs it.
|
|
38
41
|
|
|
39
42
|
The setup asks a few things — language, where to keep the research, which
|
|
40
43
|
agent (it finds the installed ones and offers Claude if there is none), the
|
package/assets/lang/cs.json
CHANGED
|
@@ -610,6 +610,20 @@
|
|
|
610
610
|
"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",
|
|
611
611
|
"ui.doc.tree.ok": "{name}: data v pořádku a zapečetěná",
|
|
612
612
|
"ui.doc.tree.bad": "{name}: {n, plural, one {# problém} few {# problémy} other {# problémů}}",
|
|
613
|
+
"ui.doc.write": "zápis do rodokmenu",
|
|
614
|
+
"ui.doc.write.ok": "do jeho .strom i .git lze zapisovat",
|
|
615
|
+
"ui.doc.write.sandbox": "{where}: zápis odepřen – strom běží pod agentem, nejspíš to zakazuje jeho sandbox",
|
|
616
|
+
"ui.doc.write.sandbox.fix": "spustit příkaz mimo sandbox agenta, nebo dát agentovi složku výzkumu jako zapisovatelnou",
|
|
617
|
+
"ui.doc.write.sandbox.fix.codex-strom": "spouštět strom samotný, bez roury a cd (pravidla .codex ve složce výzkumu ho pustí ze sandboxu Codexu; Codex je čte ve složce, které důvěřuje – znovu je zapíše strom agents sync), nebo schválit příkaz mimo sandbox Codexu (Codex se zeptá), nebo v nastavení zvolit úroveň „plná“ – volba jen člověka",
|
|
618
|
+
"ui.doc.write.sandbox.fix.codex": "spustit Codex ve složce výzkumu a důvěřovat jí (pravidla .codex v ní pustí strom ze sandboxu), nebo ho spustit přes strom („Pokračovat ve výzkumu s agentem“ v menu, nebo strom chat), nebo schválit příkaz mimo jeho sandbox",
|
|
619
|
+
"ui.doc.write.sandbox.fix.claude": "spustit Claude Code ve složce výzkumu (strom chat to tak dělá), nebo schválit příkaz mimo jeho sandbox",
|
|
620
|
+
"ui.doc.write.refused": "{where}: zápis odepřen – chybí právo zápisu",
|
|
621
|
+
"ui.doc.write.refused.fix": "složka, do které lze zapisovat",
|
|
622
|
+
"ui.doc.write.refused.fix.windows": "složka, do které lze zapisovat – zápisu může bránit i OneDrive nebo řízený přístup ke složkám v Zabezpečení Windows",
|
|
623
|
+
"ui.doc.write.refused.fix.agent": "strom spustil {agent}: nejspíš jeho sandbox – příkaz schválit mimo něj, nebo {agent} nechat pracovat na úrovni bez sandboxu; jinak složka, do které lze zapisovat",
|
|
624
|
+
"ui.doc.write.refused.fix.agent.windows": "strom spustil {agent}: nejspíš jeho sandbox – příkaz schválit mimo něj, nebo {agent} nechat pracovat na úrovni bez sandboxu; jinak složka, do které lze zapisovat – zápisu může bránit i OneDrive nebo řízený přístup ke složkám v Zabezpečení Windows",
|
|
625
|
+
"ui.doc.write.nolink": "{where}: disk neumí pevné odkazy – zámek jede náhradní cestou (pomalejší, když pracuje víc procesů naráz)",
|
|
626
|
+
"ui.doc.write.nolink.fix": "složka na vlastním disku tohoto počítače",
|
|
613
627
|
"ui.doc.allok": "Všechno potřebné je na místě.",
|
|
614
628
|
"ui.doc.problems": "{n, plural, one {# problém} few {# problémy} other {# problémů}} – co udělat, říkají šipky (strom setup nabídne instalaci toho, co chybí).",
|
|
615
629
|
"ui.menu.fix": "Opravit to hned?",
|
|
@@ -1516,6 +1530,7 @@
|
|
|
1516
1530
|
"ui.check.found": "{errors, plural, one {# chyba} few {# chyby} other {# chyb}}, {warnings} varování",
|
|
1517
1531
|
"ui.check.unproven": "pozn.: osob, které nestojí na žádném vlastním záznamu: {n} → strom person list --unproven",
|
|
1518
1532
|
"ui.check.counter": "počítadlo {prefix} zaostává za existujícími čísly (srovná se samo při příštím zápisu)",
|
|
1533
|
+
"ui.check.unwritable": "zápis sem je odepřen – proč, řekne strom doctor",
|
|
1519
1534
|
"ui.export.file": "{file} ({for}) — {persons, plural, one {# osoba} few {# osoby} other {# osob}} · {families, plural, one {# rodina} few {# rodiny} other {# rodin}} · {facts, plural, one {# údaj} few {# údaje} other {# údajů}} · {sources, plural, one {# pramen} few {# prameny} other {# pramenů}}{skipped}",
|
|
1520
1535
|
"ui.export.for.strom": "pro aplikaci Strom",
|
|
1521
1536
|
"ui.export.for.strom.images": "pro aplikaci Strom, s obrázky",
|
|
@@ -2194,10 +2209,24 @@
|
|
|
2194
2209
|
"ui.error.pack.missing.hint": "zadat ZIP soubor, který přišel (přetáhnout ho do terminálu)",
|
|
2195
2210
|
"ui.error.pack.no-manifest": "v {path} není {manifest}: není to výzkum zabalený stromem",
|
|
2196
2211
|
"ui.error.pack.no-manifest.hint": "zadat ZIP soubor, který přišel",
|
|
2197
|
-
"ui.error.fs.no-permission": "chybí
|
|
2212
|
+
"ui.error.fs.no-permission": "chybí oprávnění: {where}",
|
|
2198
2213
|
"ui.error.fs.no-permission.hint": "vybrat složku, do které lze zapisovat",
|
|
2199
2214
|
"ui.error.fs.held": "soubor {file} drží jiný program (antivirus, synchronizace nebo záloha, editor)",
|
|
2200
2215
|
"ui.error.fs.held.hint": "za chvíli spustit tentýž příkaz znovu – nic z něj se neuložilo",
|
|
2216
|
+
"ui.error.fs.no-permission.windows.hint": "vybrat složku, do které lze zapisovat – na Windows může zápisu bránit i OneDrive nebo řízený přístup ke složkám v Zabezpečení Windows",
|
|
2217
|
+
"ui.error.fs.no-permission.agent.hint": "strom spustil {agent} a zápis nejspíš zakazuje jeho sandbox: příkaz schválit mimo sandbox, nebo {agent} nechat pracovat na úrovni bez sandboxu; jinak vybrat složku, do které lze zapisovat",
|
|
2218
|
+
"ui.error.fs.no-permission.agent.windows.hint": "strom spustil {agent} a zápis nejspíš zakazuje jeho sandbox: příkaz schválit mimo sandbox, nebo {agent} nechat pracovat na úrovni bez sandboxu; jinak vybrat složku, do které lze zapisovat – na Windows může zápisu bránit i OneDrive nebo řízený přístup ke složkám v Zabezpečení Windows",
|
|
2219
|
+
"ui.error.fs.no-permission.unseen.hint": "strom nevidí programy, které ho spustily, jako v sandboxu agenta: když strom spustil agent, zápis nejspíš zakazuje jeho sandbox – příkaz schválit mimo sandbox; jinak vybrat složku, do které lze zapisovat",
|
|
2220
|
+
"ui.error.fs.no-permission.unseen.windows.hint": "strom nevidí programy, které ho spustily, jako v sandboxu agenta: když strom spustil agent, zápis nejspíš zakazuje jeho sandbox – příkaz schválit mimo sandbox; jinak vybrat složku, do které lze zapisovat – na Windows může zápisu bránit i OneDrive nebo řízený přístup ke složkám v Zabezpečení Windows",
|
|
2221
|
+
"ui.error.fs.sandboxed": "chybí oprávnění: {where} – strom běží pod agentem a nejspíš to zakazuje jeho sandbox",
|
|
2222
|
+
"ui.error.fs.sandboxed.hint": "spustit příkaz mimo sandbox agenta, nebo pracovat ve složce výzkumu (i s jejími .git a .strom zapisovatelnými)",
|
|
2223
|
+
"ui.error.git.unwritable": "git nemůže zapisovat do výzkumu: {where}",
|
|
2224
|
+
"ui.error.git.unwritable.hint": "vybrat složku, do které lze zapisovat",
|
|
2225
|
+
"ui.error.fs.folder": "místo souboru je zadaná složka: {path}",
|
|
2226
|
+
"ui.error.init.unwritable": "rodokmen nejde založit v {where}: zápis tam je odepřen – nic z něj tam nezůstalo",
|
|
2227
|
+
"ui.error.init.unwritable.hint": "vybrat složku, do které lze zapisovat",
|
|
2228
|
+
"ui.error.init.failed": "rodokmen nejde založit v {where}: {detail} – nic z něj tam nezůstalo",
|
|
2229
|
+
"ui.error.init.failed.hint": "složka na vlastním disku tohoto počítače (síťový nebo přesměrovaný disk může zápis nebo historii odmítnout)",
|
|
2201
2230
|
"ui.task.none": "Žádné úkoly.",
|
|
2202
2231
|
"ui.research.none": "Žádné linie výzkumu.",
|
|
2203
2232
|
"ui.person.none": "Žádné osoby.",
|
|
@@ -2270,6 +2299,10 @@
|
|
|
2270
2299
|
"ui.error.backup.failed.hint": "Uvolnit místo na disku ({where}) a spustit strom znovu – nebo se vrátit: strom update --channel {back}",
|
|
2271
2300
|
"ui.error.backup.failed.update": "Zálohu před přechodem z {from} na {to} se nepodařilo vytvořit: {detail}. Nic se nenainstalovalo.",
|
|
2272
2301
|
"ui.error.backup.failed.update.hint": "Uvolnit místo na disku ({where}) a znovu strom update --channel {channel}",
|
|
2302
|
+
"ui.error.backup.failed.refused.hint": "Zápis do {where} je odepřen: vybrat složku, do které lze zapisovat, pak spustit strom znovu – nebo se vrátit: strom update --channel {back}",
|
|
2303
|
+
"ui.error.backup.failed.other.hint": "Spustit strom znovu (víc řekne strom doctor) – nebo se vrátit: strom update --channel {back}",
|
|
2304
|
+
"ui.error.backup.failed.update.refused.hint": "Zápis do {where} je odepřen: vybrat složku, do které lze zapisovat, pak znovu strom update --channel {channel}",
|
|
2305
|
+
"ui.error.backup.failed.update.other.hint": "Znovu strom update --channel {channel} (víc řekne strom doctor)",
|
|
2273
2306
|
"ui.error.folder.in-program": "{folder} leží ve složce programu strom {program} – aktualizace ji nahrazuje a odinstalace odstraňuje, výzkum by šel s ní. Nic se nezměnilo.",
|
|
2274
2307
|
"ui.error.folder.in-program.hint": "Zvolit složku mimo ni, například {suggested}",
|
|
2275
2308
|
"ui.error.folder.in-program.default.hint": "Zadat složku mimo ni: strom setup --home \"{suggested}\" --yes",
|
package/assets/lang/de.json
CHANGED
|
@@ -610,6 +610,20 @@
|
|
|
610
610
|
"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",
|
|
611
611
|
"ui.doc.tree.ok": "{name}: Daten in Ordnung und versiegelt",
|
|
612
612
|
"ui.doc.tree.bad": "{name}: {n, plural, one {# Problem} other {# Probleme}}",
|
|
613
|
+
"ui.doc.write": "Schreiben in diesen Stammbaum",
|
|
614
|
+
"ui.doc.write.ok": "in sein .strom und .git kann geschrieben werden",
|
|
615
|
+
"ui.doc.write.sandbox": "{where}: Schreiben verweigert – strom läuft unter einem Agenten, wahrscheinlich verbietet es dessen Sandbox",
|
|
616
|
+
"ui.doc.write.sandbox.fix": "den Befehl außerhalb der Sandbox des Agenten ausführen, oder dem Agenten den Ordner der Forschung als beschreibbar geben",
|
|
617
|
+
"ui.doc.write.sandbox.fix.codex-strom": "strom allein ausführen, ohne Pipe und cd (die Regeln in .codex im Ordner der Forschung lassen es aus der Sandbox von Codex; Codex liest sie in einem Ordner, dem es vertraut – strom agents sync schreibt sie neu), oder den Befehl außerhalb der Sandbox von Codex genehmigen (Codex fragt), oder in den Einstellungen die Stufe „voll“ wählen – allein die Wahl des Menschen",
|
|
618
|
+
"ui.doc.write.sandbox.fix.codex": "Codex im Ordner der Forschung starten und ihm vertrauen (die Regeln in .codex lassen strom aus der Sandbox), oder über strom starten („Die Forschung mit dem Agenten fortsetzen“ im Menü, oder strom chat), oder den Befehl außerhalb seiner Sandbox genehmigen",
|
|
619
|
+
"ui.doc.write.sandbox.fix.claude": "Claude Code im Ordner der Forschung starten (strom chat tut das), oder den Befehl außerhalb seiner Sandbox genehmigen",
|
|
620
|
+
"ui.doc.write.refused": "{where}: Schreiben verweigert – keine Schreibberechtigung",
|
|
621
|
+
"ui.doc.write.refused.fix": "ein Ordner, in den geschrieben werden darf",
|
|
622
|
+
"ui.doc.write.refused.fix.windows": "ein Ordner, in den geschrieben werden darf – auch OneDrive oder der überwachte Ordnerzugriff der Windows-Sicherheit kann das Schreiben verhindern",
|
|
623
|
+
"ui.doc.write.refused.fix.agent": "strom wurde von {agent} gestartet: vermutlich dessen Sandbox – den Befehl außerhalb genehmigen oder {agent} auf einer Stufe ohne Sandbox arbeiten lassen; sonst ein Ordner, in den geschrieben werden darf",
|
|
624
|
+
"ui.doc.write.refused.fix.agent.windows": "strom wurde von {agent} gestartet: vermutlich dessen Sandbox – den Befehl außerhalb genehmigen oder {agent} auf einer Stufe ohne Sandbox arbeiten lassen; sonst ein Ordner, in den geschrieben werden darf – auch OneDrive oder der überwachte Ordnerzugriff der Windows-Sicherheit kann das Schreiben verhindern",
|
|
625
|
+
"ui.doc.write.nolink": "{where}: das Laufwerk kann keine festen Verknüpfungen – die Sperre geht einen anderen Weg (langsamer, wenn mehrere zugleich arbeiten)",
|
|
626
|
+
"ui.doc.write.nolink.fix": "ein Ordner auf der eigenen Festplatte dieses Computers",
|
|
613
627
|
"ui.doc.allok": "Alles Nötige ist vorhanden.",
|
|
614
628
|
"ui.doc.problems": "{n, plural, one {# Problem} other {# Probleme}} – den Pfeilen folgen (strom setup bietet an, Fehlendes zu installieren).",
|
|
615
629
|
"ui.menu.fix": "Jetzt beheben?",
|
|
@@ -1516,6 +1530,7 @@
|
|
|
1516
1530
|
"ui.check.found": "{errors} Fehler, {warnings, plural, one {# Warnung} other {# Warnungen}}",
|
|
1517
1531
|
"ui.check.unproven": "Hinweis: Personen, die sich auf keinen eigenen Eintrag stützen: {n} → strom person list --unproven",
|
|
1518
1532
|
"ui.check.counter": "Zähler {prefix} liegt hinter den vorhandenen Nummern (gleicht sich beim nächsten Schreiben selbst aus)",
|
|
1533
|
+
"ui.check.unwritable": "Schreiben hierher verweigert – warum, sagt strom doctor",
|
|
1519
1534
|
"ui.export.file": "{file} ({for}) — {persons, plural, one {# Person} other {# Personen}} · {families, plural, one {# Familie} other {# Familien}} · {facts, plural, one {# Angabe} other {# Angaben}} · {sources, plural, one {# Quelle} other {# Quellen}}{skipped}",
|
|
1520
1535
|
"ui.export.for.strom": "für die Strom-App",
|
|
1521
1536
|
"ui.export.for.strom.images": "für die Strom-App, mit Bildern",
|
|
@@ -2194,10 +2209,24 @@
|
|
|
2194
2209
|
"ui.error.pack.missing.hint": "die ZIP-Datei angeben, die gekommen ist (ins Terminal ziehen)",
|
|
2195
2210
|
"ui.error.pack.no-manifest": "keine {manifest} in {path}: keine von strom gepackte Forschung",
|
|
2196
2211
|
"ui.error.pack.no-manifest.hint": "die ZIP-Datei angeben, die gekommen ist",
|
|
2197
|
-
"ui.error.fs.no-permission": "keine Berechtigung{where}",
|
|
2212
|
+
"ui.error.fs.no-permission": "keine Berechtigung: {where}",
|
|
2198
2213
|
"ui.error.fs.no-permission.hint": "einen Ordner wählen, in den geschrieben werden darf",
|
|
2199
2214
|
"ui.error.fs.held": "ein anderes Programm hält {file} (Virenschutz, Synchronisation oder Sicherung, Editor)",
|
|
2200
2215
|
"ui.error.fs.held.hint": "denselben Befehl gleich noch einmal ausführen – nichts davon wurde gespeichert",
|
|
2216
|
+
"ui.error.fs.no-permission.windows.hint": "einen Ordner wählen, in den geschrieben werden darf – unter Windows kann auch OneDrive oder der überwachte Ordnerzugriff der Windows-Sicherheit das Schreiben verhindern",
|
|
2217
|
+
"ui.error.fs.no-permission.agent.hint": "strom wurde von {agent} gestartet, und vermutlich verbietet dessen Sandbox das Schreiben: den Befehl außerhalb der Sandbox genehmigen oder {agent} auf einer Stufe ohne Sandbox arbeiten lassen; sonst einen Ordner wählen, in den geschrieben werden darf",
|
|
2218
|
+
"ui.error.fs.no-permission.agent.windows.hint": "strom wurde von {agent} gestartet, und vermutlich verbietet dessen Sandbox das Schreiben: den Befehl außerhalb der Sandbox genehmigen oder {agent} auf einer Stufe ohne Sandbox arbeiten lassen; sonst einen Ordner wählen, in den geschrieben werden darf – unter Windows kann auch OneDrive oder der überwachte Ordnerzugriff der Windows-Sicherheit das Schreiben verhindern",
|
|
2219
|
+
"ui.error.fs.no-permission.unseen.hint": "strom sieht die Programme nicht, die es gestartet haben, wie in der Sandbox eines Agenten: wurde strom von einem Agenten gestartet, verbietet vermutlich dessen Sandbox das Schreiben – den Befehl außerhalb der Sandbox genehmigen; sonst einen Ordner wählen, in den geschrieben werden darf",
|
|
2220
|
+
"ui.error.fs.no-permission.unseen.windows.hint": "strom sieht die Programme nicht, die es gestartet haben, wie in der Sandbox eines Agenten: wurde strom von einem Agenten gestartet, verbietet vermutlich dessen Sandbox das Schreiben – den Befehl außerhalb der Sandbox genehmigen; sonst einen Ordner wählen, in den geschrieben werden darf – unter Windows kann auch OneDrive oder der überwachte Ordnerzugriff der Windows-Sicherheit das Schreiben verhindern",
|
|
2221
|
+
"ui.error.fs.sandboxed": "keine Berechtigung: {where} – strom läuft unter einem Agenten, und wahrscheinlich verbietet es dessen Sandbox",
|
|
2222
|
+
"ui.error.fs.sandboxed.hint": "den Befehl außerhalb der Sandbox des Agenten ausführen, oder im Ordner der Forschung arbeiten (auch dessen .git und .strom beschreibbar)",
|
|
2223
|
+
"ui.error.git.unwritable": "git kann nicht in die Forschung schreiben: {where}",
|
|
2224
|
+
"ui.error.git.unwritable.hint": "einen Ordner wählen, in den geschrieben werden darf",
|
|
2225
|
+
"ui.error.fs.folder": "statt einer Datei wurde ein Ordner angegeben: {path}",
|
|
2226
|
+
"ui.error.init.unwritable": "der Stammbaum lässt sich in {where} nicht anlegen: das Schreiben dort wird verweigert – nichts davon ist dort geblieben",
|
|
2227
|
+
"ui.error.init.unwritable.hint": "einen Ordner wählen, in den geschrieben werden darf",
|
|
2228
|
+
"ui.error.init.failed": "der Stammbaum lässt sich in {where} nicht anlegen: {detail} – nichts davon ist dort geblieben",
|
|
2229
|
+
"ui.error.init.failed.hint": "ein Ordner auf der eigenen Festplatte dieses Computers (ein Netz- oder umgeleitetes Laufwerk kann das Schreiben oder den Verlauf verweigern)",
|
|
2201
2230
|
"ui.task.none": "Keine Aufgaben.",
|
|
2202
2231
|
"ui.research.none": "Keine Forschungsrichtungen.",
|
|
2203
2232
|
"ui.person.none": "Keine Personen.",
|
|
@@ -2270,6 +2299,10 @@
|
|
|
2270
2299
|
"ui.error.backup.failed.hint": "Platz auf dem Datenträger freimachen ({where}) und strom erneut starten – oder zurück: strom update --channel {back}",
|
|
2271
2300
|
"ui.error.backup.failed.update": "Die Sicherung vor dem Wechsel von {from} auf {to} ließ sich nicht erstellen: {detail}. Es wurde nichts installiert.",
|
|
2272
2301
|
"ui.error.backup.failed.update.hint": "Platz auf dem Datenträger freimachen ({where}), dann erneut strom update --channel {channel}",
|
|
2302
|
+
"ui.error.backup.failed.refused.hint": "Das Schreiben in {where} wird verweigert: einen Ordner wählen, in den geschrieben werden darf, dann strom erneut starten – oder zurück: strom update --channel {back}",
|
|
2303
|
+
"ui.error.backup.failed.other.hint": "strom erneut starten (strom doctor sagt mehr) – oder zurück: strom update --channel {back}",
|
|
2304
|
+
"ui.error.backup.failed.update.refused.hint": "Das Schreiben in {where} wird verweigert: einen Ordner wählen, in den geschrieben werden darf, dann erneut strom update --channel {channel}",
|
|
2305
|
+
"ui.error.backup.failed.update.other.hint": "Erneut strom update --channel {channel} (strom doctor sagt mehr)",
|
|
2273
2306
|
"ui.error.folder.in-program": "{folder} liegt im Programmordner von strom {program} – ein Update von strom ersetzt, was dort liegt, und die Deinstallation entfernt es, die Forschung mit. Nichts wurde geändert.",
|
|
2274
2307
|
"ui.error.folder.in-program.hint": "Einen Ordner außerhalb wählen, zum Beispiel {suggested}",
|
|
2275
2308
|
"ui.error.folder.in-program.default.hint": "Einen Ordner außerhalb angeben: strom setup --home \"{suggested}\" --yes",
|
package/dist/agents/files.js
CHANGED
|
@@ -13,7 +13,7 @@ import { PROFILES, selfReading } from "./profiles.js";
|
|
|
13
13
|
import { isArchive } from "../core/mode.js";
|
|
14
14
|
import { Settings } from "../core/config.js";
|
|
15
15
|
import { agentAppUrl, appSite } from "../core/stromapp.js";
|
|
16
|
-
import { configDir } from "../core/paths.js";
|
|
16
|
+
import { configDir, ownCommand } from "../core/paths.js";
|
|
17
17
|
import { within } from "../core/relocate.js";
|
|
18
18
|
import { agentBrowser } from "../core/connector.js";
|
|
19
19
|
import { CHROME_ALLOW, CHROME_DENY, chromeDomain } from "../core/browser.js";
|
|
@@ -50,16 +50,20 @@ the researcher; \`strom\` is your only way to read and change the research.
|
|
|
50
50
|
5. Material from the user goes in with \`strom intake <file or folder>\` or
|
|
51
51
|
\`strom intake --text "…"\`. Exit code 3 means strom needs an answer from the
|
|
52
52
|
user; exit code 4 means the USER must run the given command in their own
|
|
53
|
-
terminal — never do it yourself.
|
|
53
|
+
terminal — never do it yourself. strom saying your sandbox refused writing
|
|
54
|
+
(\`fs.sandboxed\`): never another folder or setting — ask for the command
|
|
55
|
+
to run outside your sandbox, or work in this folder (its \`.git\` and
|
|
56
|
+
\`.strom\` too).
|
|
54
57
|
6. You may read \`inputs/\`, \`output/\`, \`notes/\` and \`.strom/views/\`, and write
|
|
55
58
|
your own working notes in \`notes/\`. Scans are looked at through views:
|
|
56
59
|
\`strom media view B0001:57 --half left\` writes one to \`.strom/views/\`;
|
|
57
60
|
the views of a scan or a batch come in one call (\`B0001:57-60 --half both\`).
|
|
58
61
|
A text in those files: \`strom grep "<text>"\` (each line with its file and
|
|
59
62
|
number) — never read a big file in pieces.
|
|
60
|
-
7. Run strom commands on their own — no pipes (\`| head\`, \`| grep\`)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
7. Run strom commands on their own — no pipes (\`| head\`, \`| grep\`), no
|
|
64
|
+
redirection (\`2>&1\`), no \`cd\` before them: output is already short,
|
|
65
|
+
listings take \`--limit\` and \`--page\`, and such commands may be refused by
|
|
66
|
+
your permissions (Codex's sandbox lets strom out only on its own).${ps ? `\n ${ps}` : ""}
|
|
63
67
|
8. Other agents may work on this tree too (Claude Code, Codex, Antigravity,
|
|
64
68
|
OpenCode, Grok — the user's choice). \`strom\` shows who is working now; never take a task
|
|
65
69
|
another one has started.
|
|
@@ -257,6 +261,7 @@ function treeRules(tree, agent) {
|
|
|
257
261
|
...shell("git:*"),
|
|
258
262
|
// A password is typed by the user in their own terminal, and so is installing a plugin; the seal is strom's.
|
|
259
263
|
// (Consents the agent may ask for — strom allow …: strom asks the person in a window.)
|
|
264
|
+
// A rule matches only the command right after strom's name: strom itself refuses these to an agent (CommandDef.person).
|
|
260
265
|
...shell("strom login:*"),
|
|
261
266
|
...shell("strom connector add:*"),
|
|
262
267
|
...shell("strom connector remove:*"),
|
|
@@ -309,13 +314,41 @@ CLAUDE.md in this folder is written for Claude Code: its way of delegating (the
|
|
|
309
314
|
Agent tool, the models opus, sonnet and haiku) is not yours. Follow AGENTS.md,
|
|
310
315
|
and read scans yourself as it says under "Reading scans".
|
|
311
316
|
`;
|
|
317
|
+
/**
|
|
318
|
+
* Codex's rules for this tree (.codex/rules/strom.rules, read once the folder is trusted): strom run as a command of
|
|
319
|
+
* its own goes outside Codex's sandbox without asking — it writes the research's .strom and .git, which the sandbox
|
|
320
|
+
* keeps closed (measured 2026-10-22, codex-cli 0.163: on Windows .git stays closed even as a writable root, and nothing
|
|
321
|
+
* runs at all without a rule; on macOS too) — what the person decides stays forbidden, and git itself. Only strom's
|
|
322
|
+
* command alone: one in a pipe or after `cd` runs in the sandbox (Codex's rules match a plain command). Codex keeps
|
|
323
|
+
* .codex closed to the agent itself.
|
|
324
|
+
* The whole of strom is allowed, as for Claude Code (Bash(strom:*)): what strom writes outside the research (strom
|
|
325
|
+
* export --out, strom init <folder>) is strom's own decision, and what is the person's it refuses to an agent itself.
|
|
326
|
+
* The forbidden rules match only the command right after strom's name (strom --json seal adopt is not matched — a
|
|
327
|
+
* value-taking option cannot be listed): they are the second layer and give the agent the reason; the first is strom
|
|
328
|
+
* refusing the user's own commands to any agent, whatever comes before them (CommandDef.person).
|
|
329
|
+
*/
|
|
330
|
+
export function codexRules(tree) {
|
|
331
|
+
const own = ownCommand(tree.env);
|
|
332
|
+
const names = JSON.stringify(["strom", "strom.cmd", ...(own ? [own, `${own}.cmd`] : [])]);
|
|
333
|
+
const rule = (pattern, decision, why) => `prefix_rule(pattern = [${pattern}], decision = "${decision}", justification = ${JSON.stringify(why)})`;
|
|
334
|
+
return [
|
|
335
|
+
"# strom: generated (strom agents sync) — Codex's rules for this family tree; changed by strom only",
|
|
336
|
+
rule(names, "allow", "strom writes the research (its .strom and .git) and keeps its rules"),
|
|
337
|
+
rule(`${names}, ["login", "seal"]`, "forbidden", "a login and the seal are the user's own"),
|
|
338
|
+
rule(`${names}, "connector", ["add", "remove"]`, "forbidden", "installing a plugin is the user's own"),
|
|
339
|
+
rule('"git"', "forbidden", "strom keeps the history: never git itself"),
|
|
340
|
+
"",
|
|
341
|
+
].join("\n");
|
|
342
|
+
}
|
|
343
|
+
export const CODEX_RULES = path.join(".codex", "rules", "strom.rules");
|
|
312
344
|
/** Denied as well when the user lets the agent do everything else (agent.permissions full). */
|
|
313
345
|
export const BYPASS_DENY = [
|
|
314
346
|
// its own permissions and instructions
|
|
315
347
|
"Edit(.claude/**)",
|
|
316
348
|
...["AGENTS.md", "CLAUDE.md"].map((f) => `Edit(${f})`),
|
|
317
|
-
// (Grok Build's own rules and instructions)
|
|
349
|
+
// (Grok Build's and Codex's own rules and instructions)
|
|
318
350
|
"Edit(.grok/**)",
|
|
351
|
+
"Edit(.codex/**)",
|
|
319
352
|
// downloads round strom's limiter
|
|
320
353
|
"Bash(curl:*)",
|
|
321
354
|
"Bash(wget:*)",
|
|
@@ -459,6 +492,7 @@ function dropAgentFiles(tree) {
|
|
|
459
492
|
[path.join(".grok", "config.toml"), grokConfig(tree)],
|
|
460
493
|
[path.join(".grok", "rules", "strom.md"), GROK_RULES],
|
|
461
494
|
[GROK_HOOKS, JSON.stringify(grokWebHooks(tree.root), null, 2) + "\n"],
|
|
495
|
+
[CODEX_RULES, codexRules(tree)],
|
|
462
496
|
];
|
|
463
497
|
for (const [rel, content] of generated) {
|
|
464
498
|
const file = path.join(tree.root, rel);
|
|
@@ -505,7 +539,7 @@ function dropAgentFiles(tree) {
|
|
|
505
539
|
export const GROK_HOOKS = path.join(".grok", "hooks", "strom.json");
|
|
506
540
|
/** Claude Code's subagent for reading scans, in the tree. */
|
|
507
541
|
export const CLAUDE_SCAN_READER = path.join(".claude", "agents", `${SCAN_READER}.md`);
|
|
508
|
-
export const AGENT_FILES = ["AGENTS.md", "CLAUDE.md", path.join(".claude", "settings.json"), CLAUDE_SCAN_READER, "opencode.json", path.join(".grok", "config.toml"), path.join(".grok", "rules", "strom.md"), GROK_HOOKS];
|
|
542
|
+
export const AGENT_FILES = ["AGENTS.md", "CLAUDE.md", path.join(".claude", "settings.json"), CLAUDE_SCAN_READER, "opencode.json", path.join(".grok", "config.toml"), path.join(".grok", "rules", "strom.md"), GROK_HOOKS, CODEX_RULES];
|
|
509
543
|
/**
|
|
510
544
|
* strom's files of the agents written for the tree (only what changed: the files written, to commit). `said.shim`: the
|
|
511
545
|
* shim in .strom/bin was written now (never committed: not among the files).
|
|
@@ -540,6 +574,7 @@ export function syncAgentFiles(tree, said = {}) {
|
|
|
540
574
|
write(path.join(".grok", "config.toml"), grokConfig(tree));
|
|
541
575
|
write(path.join(".grok", "rules", "strom.md"), GROK_RULES);
|
|
542
576
|
write(GROK_HOOKS, JSON.stringify(grokWebHooks(tree.root), null, 2) + "\n");
|
|
577
|
+
write(CODEX_RULES, codexRules(tree));
|
|
543
578
|
// the strom the agent hooks name (the tree's .strom/bin, never committed) — there also for a conversation strom did not start
|
|
544
579
|
if (!tree.dryRun) {
|
|
545
580
|
try {
|
package/dist/agents/global.js
CHANGED
|
@@ -56,7 +56,9 @@ mentions strom, a family tree or the Strom app.
|
|
|
56
56
|
"Continue the research with the agent".
|
|
57
57
|
6. When strom needs the user's consent it opens a window on their screen —
|
|
58
58
|
tell them to answer it; you cannot. Exit code 4 means the user must run
|
|
59
|
-
the given command themselves.
|
|
59
|
+
the given command themselves. strom saying your sandbox refused writing
|
|
60
|
+
(\`fs.sandboxed\`): never another folder or setting — ask for the command
|
|
61
|
+
to run outside your sandbox, or work in the family tree's folder.
|
|
60
62
|
7. Old handwriting is read by your strongest model — never a faster or
|
|
61
63
|
cheaper model, subagent or pass; a name or place the next search depends
|
|
62
64
|
on is read again on an enlarged crop before it is recorded.
|
package/dist/agents/launch.js
CHANGED
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
//
|
|
18
18
|
// Claude Code always gets the tree's allow and deny lists (--settings); Codex
|
|
19
19
|
// works in its sandbox on the tree folder with its .git (strom commits) and the
|
|
20
|
-
// shared folder writable and the network on (strom fetches)
|
|
20
|
+
// shared folder writable and the network on (strom fetches) — and strom itself
|
|
21
|
+
// runs outside it by the tree's rules (.codex/rules/strom.rules): on Windows its
|
|
22
|
+
// sandbox keeps .git closed though it is named writable.
|
|
21
23
|
import { claudeArgs } from "../runners/claude.js";
|
|
22
24
|
import { codexTrust, codexWritable } from "../runners/codex.js";
|
|
23
25
|
import { grokOwnEnv, grokTrust } from "../runners/grok.js";
|
package/dist/cli/backups.js
CHANGED
|
@@ -4,6 +4,8 @@ import { EXIT, StromError } from "../core/errors.js";
|
|
|
4
4
|
import { backupOnce, backupsDir, BackupFailed, mb } from "../core/backup.js";
|
|
5
5
|
import { installation, replacedHolding } from "../core/self.js";
|
|
6
6
|
import { ui } from "./ui.js";
|
|
7
|
+
import { isAgent } from "../core/which.js";
|
|
8
|
+
import { refusedCode, SANDBOX_HINT } from "../core/writable.js";
|
|
7
9
|
/** A local date and time for a sentence. */
|
|
8
10
|
function when(iso) {
|
|
9
11
|
const d = new Date(iso);
|
|
@@ -50,17 +52,34 @@ export function backupBefore(ctx, t, opts = {}) {
|
|
|
50
52
|
const where = backupsDir(home);
|
|
51
53
|
const back = t.fromChannel ?? "stable";
|
|
52
54
|
const params = { ...said, detail, where, back, channel: opts.update?.channel ?? "" };
|
|
55
|
+
// room on the disk only where the disk is full (found on Windows: an agent's sandbox refused the backup's lock, EPERM,
|
|
56
|
+
// and strom advised freeing room); a refused write says so — under an agent most likely its sandbox
|
|
57
|
+
const code = e instanceof BackupFailed ? e.code : e.code;
|
|
58
|
+
const why = (e instanceof BackupFailed && e.room) || code === "ENOSPC" ? "room" : refusedCode(code) ? "refused" : "other";
|
|
59
|
+
const agent = isAgent(ctx.env);
|
|
53
60
|
if (opts.update)
|
|
54
61
|
throw new StromError(`the backup before going from ${said.from} to ${said.to} could not be made: ${detail} — nothing was installed`, {
|
|
55
62
|
exitCode: EXIT.noBackup,
|
|
56
|
-
hint:
|
|
63
|
+
hint: why === "room"
|
|
64
|
+
? `free room on the disk (${where}), then strom update --channel ${opts.update.channel} again`
|
|
65
|
+
: why === "refused"
|
|
66
|
+
? `${agent ? `writing into ${where} was refused — ${SANDBOX_HINT}` : `writing into ${where} is refused: a folder with the right to write in it`}; then strom update --channel ${opts.update.channel} again`
|
|
67
|
+
: `strom doctor says more; then strom update --channel ${opts.update.channel} again`,
|
|
68
|
+
...(why !== "room" ? { hintCode: `backup.failed.update.${why}` } : {}),
|
|
57
69
|
code: "backup.failed.update",
|
|
58
70
|
params,
|
|
59
71
|
details: { from: t.from, to: t.to, where, ...(e instanceof BackupFailed && e.room ? { room: e.room } : {}) },
|
|
60
72
|
});
|
|
61
73
|
throw new StromError(`the backup before going from ${said.from} to ${said.to} could not be made: ${detail} — nothing is switched: this strom opens no family tree for writing until it is made (tried again at each run)`, {
|
|
62
74
|
exitCode: EXIT.noBackup,
|
|
63
|
-
hint:
|
|
75
|
+
hint: why === "room"
|
|
76
|
+
? `tell the user: free room on the disk (${where}), then run strom again — or go back: strom update --channel ${back}`
|
|
77
|
+
: why === "refused"
|
|
78
|
+
? agent
|
|
79
|
+
? `writing into ${where} was refused — ${SANDBOX_HINT}`
|
|
80
|
+
: `writing into ${where} is refused: a folder with the right to write in it, then run strom again — or go back: strom update --channel ${back}`
|
|
81
|
+
: `strom doctor says more; run strom again — or go back: strom update --channel ${back}`,
|
|
82
|
+
...(why !== "room" ? { hintCode: `backup.failed.${why}` } : {}),
|
|
64
83
|
code: "backup.failed",
|
|
65
84
|
params,
|
|
66
85
|
details: { from: t.from, to: t.to, where, ...(e instanceof BackupFailed && e.room ? { room: e.room } : {}) },
|
package/dist/cli/main.js
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
// and commit what a writing command changed. Returns the exit code.
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import { takeOverConnectors } from "../core/terms.js";
|
|
5
|
-
import { notePersonFolder } from "../core/trust.js";
|
|
5
|
+
import { agentInAncestry, ancestryUnread, notePersonFolder } from "../core/trust.js";
|
|
6
6
|
import { netTrust } from "../core/net.js";
|
|
7
7
|
import { connectorsDir, listConnectors } from "../core/connector.js";
|
|
8
8
|
import { Cancelled, EXIT, notFound, StromError, UsageError } from "../core/errors.js";
|
|
9
9
|
import { ownCommand } from "../core/paths.js";
|
|
10
10
|
import { Context } from "./context.js";
|
|
11
11
|
import { commands, match } from "./registry.js";
|
|
12
|
-
import { asCommand, asCommandJson } from "./format.js";
|
|
12
|
+
import { asCommand, asCommandJson, shellArg } from "./format.js";
|
|
13
13
|
import { groupHelpAs, helpAs } from "./help.js";
|
|
14
14
|
import { autoCommit } from "./commit.js";
|
|
15
15
|
import { assertIntact } from "../core/integrity.js";
|
|
@@ -23,6 +23,7 @@ import { fireHooks, HOOK_INTERFACE } from "../core/hooks.js";
|
|
|
23
23
|
import { prependPath } from "../runners/runner.js";
|
|
24
24
|
import { shimDir } from "../commands/session.js";
|
|
25
25
|
import { isAgent } from "../core/which.js";
|
|
26
|
+
import { noPermission } from "../core/writable.js";
|
|
26
27
|
import { completePath, pathOf, pathToRemember } from "../core/userpath.js";
|
|
27
28
|
import { appUrlShown, noticeStromApp } from "../core/stromapp.js";
|
|
28
29
|
import { lastChannelOf, pendingTransition, updateChannel, whatsNewUrl } from "../core/update.js";
|
|
@@ -53,8 +54,11 @@ function print(io, ctx, result) {
|
|
|
53
54
|
else if (result.text)
|
|
54
55
|
io.stdout(result.text.endsWith("\n") ? result.text : result.text + "\n");
|
|
55
56
|
}
|
|
56
|
-
/**
|
|
57
|
-
|
|
57
|
+
/**
|
|
58
|
+
* File-system errors in plain words (a missing @file, a folder without rights — under an agent most likely its
|
|
59
|
+
* sandbox, core/writable.ts).
|
|
60
|
+
*/
|
|
61
|
+
function systemError(e, agent) {
|
|
58
62
|
const where = e.path ? `: ${e.path}` : "";
|
|
59
63
|
// a file another program held past the waits (Windows: an antivirus, a sync tool, an editor) — no lack of rights:
|
|
60
64
|
// running it again does it (what the command wrote was taken back)
|
|
@@ -65,9 +69,10 @@ function systemError(e) {
|
|
|
65
69
|
return e.path ? notFound(e.path) : new UsageError("no such file or folder", { hint: "check the path (relative paths start in the current folder)" });
|
|
66
70
|
case "EACCES":
|
|
67
71
|
case "EPERM":
|
|
68
|
-
|
|
72
|
+
case "EROFS":
|
|
73
|
+
return noPermission(e.path, agent);
|
|
69
74
|
case "EISDIR":
|
|
70
|
-
return new UsageError(`a folder was given where a file is expected${where}
|
|
75
|
+
return new UsageError(`a folder was given where a file is expected${where}`, { code: "fs.folder", ...(e.path ? { params: { path: e.path } } : {}) });
|
|
71
76
|
case "ENOTDIR":
|
|
72
77
|
return new UsageError(`a file was given where a folder is expected${where}`);
|
|
73
78
|
case "ENOSPC":
|
|
@@ -97,8 +102,27 @@ function inLanguage(e, lang) {
|
|
|
97
102
|
const say = (text) => placeholders(lang, text);
|
|
98
103
|
return { message: say(localized(lang, key, message, e.params)), ...(e.hint ? { hint: say(hint ? localized(lang, hintKey, hint, e.params) : e.hint) } : {}), prefix: ui(lang, "ui.error.prefix") };
|
|
99
104
|
}
|
|
100
|
-
|
|
101
|
-
|
|
105
|
+
const REFUSALS = new Set(["fs.no-permission", "git.unwritable", "init.unwritable"]);
|
|
106
|
+
/**
|
|
107
|
+
* A refusal to write under an agent: most likely its sandbox — said so, with what the agent does (core/writable.ts).
|
|
108
|
+
* Without an agent's marks, an agent among strom's parent processes (read here only, on a refusal: found on Windows,
|
|
109
|
+
* Codex's sandbox ran strom with none of its marks) is named to the person as the likely cause — not certain, so
|
|
110
|
+
* the other causes after it.
|
|
111
|
+
*/
|
|
112
|
+
function underAgent(e, env) {
|
|
113
|
+
if (!REFUSALS.has(e.code ?? ""))
|
|
114
|
+
return e;
|
|
115
|
+
if (isAgent(env))
|
|
116
|
+
return noPermission(e.params?.where, env);
|
|
117
|
+
const above = agentInAncestry(env);
|
|
118
|
+
if (above)
|
|
119
|
+
return noPermission(e.params?.where, false, process.platform, above);
|
|
120
|
+
return ancestryUnread(env) ? noPermission(e.params?.where, false, process.platform, "?") : e;
|
|
121
|
+
}
|
|
122
|
+
function printError(io, json, err, debug, lang, env) {
|
|
123
|
+
const agent = isAgent(env) && env;
|
|
124
|
+
const sys = err instanceof StromError ? err : (systemError(err, agent) ?? err);
|
|
125
|
+
const e = sys instanceof StromError ? underAgent(sys, env) : sys;
|
|
102
126
|
if (e instanceof StromError) {
|
|
103
127
|
if (json)
|
|
104
128
|
io.stdout(toJson(e.toJSON()));
|
|
@@ -221,6 +245,13 @@ export async function main(argv, io, env, cwd) {
|
|
|
221
245
|
.map((x) => `${x[0].toUpperCase()}${x.slice(1).padStart(4, "0")}`);
|
|
222
246
|
ran = ctx;
|
|
223
247
|
command = def.path.join(" ");
|
|
248
|
+
// What the user does in their own terminal (a login, the seal, a plugin installed): refused to an agent here, after
|
|
249
|
+
// every option is read — the agents' rules match only what follows the command's name (strom --json seal adopt
|
|
250
|
+
// passed Codex's), so they are a second layer and strom the first
|
|
251
|
+
if (def.person && isAgent(env)) {
|
|
252
|
+
const said = (def.options ?? []).flatMap((o) => (v[o.name] === undefined || v[o.name] === false ? [] : o.type === "boolean" ? [`--${o.name}`] : [`--${o.name}`, String(v[o.name])]));
|
|
253
|
+
ctx.requireHuman(def.person, ["strom", ...def.path, ...[...parsed.positionals, ...said].map(shellArg)].join(" "), def.path[0], undefined, { window: false });
|
|
254
|
+
}
|
|
224
255
|
// The PATH of the person's terminal remembered (never an agent's, a hook's, one strom started); a strom the system
|
|
225
256
|
// started (a link from the Strom app, the bridge, the phone's server) gets what of it is missing — and so do the
|
|
226
257
|
// agents and readers it starts (core/userpath.ts)
|
|
@@ -474,7 +505,7 @@ export async function main(argv, io, env, cwd) {
|
|
|
474
505
|
// the usage is the agent's (or a program's): a person reads the error and its hint in their language, no English
|
|
475
506
|
if (said instanceof StromError && said.usage && !json && !isAgent(env))
|
|
476
507
|
said.usage = undefined;
|
|
477
|
-
const code = printError(io, json, said, debug, lang);
|
|
508
|
+
const code = printError(io, json, said, debug, lang, env);
|
|
478
509
|
remind(io, ran, command, Date.now() - startedAt);
|
|
479
510
|
return code;
|
|
480
511
|
}
|
package/dist/cli/registry.js
CHANGED
|
@@ -118,6 +118,9 @@ export function describe(def, appUrl) {
|
|
|
118
118
|
out.writes = true;
|
|
119
119
|
if (def.tree)
|
|
120
120
|
out.needsTree = true;
|
|
121
|
+
// the user's own, in their terminal: refused to an agent
|
|
122
|
+
if (def.person)
|
|
123
|
+
out.userOnly = true;
|
|
121
124
|
if (def.aliases?.length)
|
|
122
125
|
out.aliases = def.aliases.map((a) => a.join(" "));
|
|
123
126
|
if (def.args?.length)
|