@lamemind/loom-deck 0.33.0 → 0.34.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/README.md +4 -4
- package/dist/cli.js +26 -17
- package/dist/pane-views.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -45,8 +45,8 @@ Regola unica, senza eccezioni — pensata per reggere l'aggiunta di nuove azioni
|
|
|
45
45
|
| Tasto | Semantica | Note |
|
|
46
46
|
|---|---|---|
|
|
47
47
|
| `↑` `↓` | naviga nella lista | |
|
|
48
|
-
|
|
|
49
|
-
|
|
|
48
|
+
| `←` `→` | cambia pane | assoluto, non toggle: `←` = Tasks, `→` = Sessions — la direzione nomina il pane, che è affiancato |
|
|
49
|
+
| `tab` | cambia **vista** del pane a fuoco | ciclico (`shift+tab` indietro); il catalogo è l'header stesso |
|
|
50
50
|
| `⏎` | azione primaria del pane | Tasks → apre il **detail** della task selezionata · Sessions → riprende (`claude --resume`) la sessione selezionata |
|
|
51
51
|
| **MAIUSCOLA** | **apre un modale** | cattura tutti i tasti; `esc` annulla, non esce |
|
|
52
52
|
| minuscola | azione immediata, one-shot | |
|
|
@@ -122,7 +122,7 @@ Le azioni non sono un catalogo nuovo: chiamano lo **stesso** percorso di spawn d
|
|
|
122
122
|
|
|
123
123
|
Sono bottoni affiancati e non voci di un menu verticale perché è la forma che sopravvive all'arrivo del mouse: un rettangolo ha già coordinate e area cliccabile, una lista di voci andrebbe rifatta.
|
|
124
124
|
|
|
125
|
-
Dentro il detail `←→` cicla i bottoni invece di cambiare la vista
|
|
125
|
+
Dentro il detail `←→` cicla i bottoni invece di cambiare pane, e `tab` non cambia la vista — il
|
|
126
126
|
ramo `useInput` della modalità chiude prima di arrivare a quello di default. Ink non ha focus-trap: la cattura **è** l'ordine dei rami, e cambiare cosa fa un tasto fuori dal detail non tocca cosa fa dentro.
|
|
127
127
|
|
|
128
128
|
Il catalogo dei prompt vive in `scripts/deck-run`, non nella TUI: è il primitive UI-agnostico, il deck gli passa un **simbolo** (`--prompt-kind`) e non una stringa. Così il testo sta in un posto solo, e con lui il suo vincolo di quoting — il prompt viaggia dentro apici singoli in `bash -lc`, quindi non può contenerne.
|
|
@@ -209,7 +209,7 @@ e al riavvio viene ripristinata. File assente o corrotto → default puliti.
|
|
|
209
209
|
## L'header è un selettore di vista
|
|
210
210
|
|
|
211
211
|
Ogni segmento dell'header nomina un sottoinsieme che il deck sa già calcolare.
|
|
212
|
-
|
|
212
|
+
`tab` lo rende **raggiungibile**: la voce attiva si evidenzia in video
|
|
213
213
|
inverso e la lista sotto mostra quel sottoinsieme.
|
|
214
214
|
|
|
215
215
|
```
|
package/dist/cli.js
CHANGED
|
@@ -628,7 +628,7 @@ function Deck({ cwd, tasksPath, tasksDir }) {
|
|
|
628
628
|
// modale: la lista si aggiorna dal vivo, quindi `esc` deve poter ripristinare.
|
|
629
629
|
const [view, setView] = useState(() => loadView(cwd));
|
|
630
630
|
const [viewBackup, setViewBackup] = useState(null);
|
|
631
|
-
// T100 — vista attiva di ciascun pane, navigata con
|
|
631
|
+
// T100 — vista attiva di ciascun pane, navigata con `tab`. VOLATILE per
|
|
632
632
|
// decisione (D3 create): non entra in `deck-view.json`, il deck riapre sempre
|
|
633
633
|
// su `Tasks` e su `{parent}`. Il criterio è il rischio di leggere una lista
|
|
634
634
|
// parziale credendola completa — un filtro salvato lo si è scelto, una vista
|
|
@@ -990,7 +990,7 @@ function Deck({ cwd, tasksPath, tasksDir }) {
|
|
|
990
990
|
// messaggi a mano. `verb` è l'unica cosa che cambia fra i due usi.
|
|
991
991
|
function selectedTaskOr(keyLabel, verb) {
|
|
992
992
|
if (focus !== 'tasks') {
|
|
993
|
-
setNote(`${keyLabel} → ${verb}: seleziona una task (
|
|
993
|
+
setNote(`${keyLabel} → ${verb}: seleziona una task (← per il pane)`);
|
|
994
994
|
return null;
|
|
995
995
|
}
|
|
996
996
|
// T59 — la guardia è "non è una task", non "è spot": le righe meta sono due
|
|
@@ -1241,7 +1241,7 @@ function Deck({ cwd, tasksPath, tasksDir }) {
|
|
|
1241
1241
|
else
|
|
1242
1242
|
setSel(paneTasks[next - META_ROWS]?.id ?? SPOT);
|
|
1243
1243
|
}
|
|
1244
|
-
// T100 —
|
|
1244
|
+
// T100 — `tab` naviga il catalogo viste del pane in focus. Il reset della
|
|
1245
1245
|
// selezione è la regola letterale «prima riga in alto», senza eccezioni: sul
|
|
1246
1246
|
// pane task è `ROW_ALL` (D2 preflight — le righe meta non si saltano, e il
|
|
1247
1247
|
// parent delle sessioni che torna a `tutte` è un effetto accettato); sul pane
|
|
@@ -1669,7 +1669,10 @@ function Deck({ cwd, tasksPath, tasksDir }) {
|
|
|
1669
1669
|
// selezione per ognuna. Sta PRIMA del ramo di default per la stessa ragione
|
|
1670
1670
|
// di reader e ricerca — Ink non ha focus-trap, quindi la cattura È l'ordine
|
|
1671
1671
|
// dei rami — e il `return` in fondo è ciò che impedisce a `←→` di cambiare
|
|
1672
|
-
// pane mentre muove fra le azioni: qui quel binding non esiste più.
|
|
1672
|
+
// pane mentre muove fra le azioni: qui quel binding non esiste più. Cade lì
|
|
1673
|
+
// anche `tab`, cioè il cambio vista: dentro il detail nessuno dei due tasti
|
|
1674
|
+
// di navigazione del pane risponde, e non è un'eccezione da ricordare per
|
|
1675
|
+
// ognuno — è il `return` che chiude tutto il ramo di default in una volta.
|
|
1673
1676
|
// È anche prima del ramo CTRL, quindi `^K`/`^P`/`^R` restano acceleratori
|
|
1674
1677
|
// della sola lista: chi è già nel detail ha i bottoni.
|
|
1675
1678
|
if (mode === 'detail') {
|
|
@@ -1794,16 +1797,22 @@ function Deck({ cwd, tasksPath, tasksDir }) {
|
|
|
1794
1797
|
return;
|
|
1795
1798
|
}
|
|
1796
1799
|
if (key.tab) {
|
|
1797
|
-
//
|
|
1798
|
-
//
|
|
1799
|
-
//
|
|
1800
|
-
//
|
|
1801
|
-
//
|
|
1802
|
-
//
|
|
1803
|
-
|
|
1800
|
+
// `tab` cicla la VISTA del pane a fuoco, `←→` spostano il focus fra i due
|
|
1801
|
+
// pane: il criterio dell'assegnazione è spaziale. Una freccia orizzontale
|
|
1802
|
+
// porta con sé una direzione e i pane sono affiancati (task a sinistra,
|
|
1803
|
+
// sessioni a destra), quindi il tasto NOMINA il pane invece di limitarsi
|
|
1804
|
+
// a scambiarlo; un catalogo ciclico non ha un verso da rispettare, e un
|
|
1805
|
+
// tasto solo gli basta. `shift+tab` (backtab, `[Z`) scorre a rovescio — il
|
|
1806
|
+
// verso che un tasto singolo non esprime sta nel modificatore, e su cinque
|
|
1807
|
+
// voci risparmia quattro pressioni.
|
|
1808
|
+
cycleView(key.shift ? -1 : 1);
|
|
1804
1809
|
}
|
|
1805
1810
|
else if (key.leftArrow || key.rightArrow) {
|
|
1806
|
-
|
|
1811
|
+
// Binding ASSOLUTO, non toggle: `←` porta sempre sui task e `→` sempre
|
|
1812
|
+
// sulle sessioni, quindi ripremere lo stesso tasto non riporta indietro.
|
|
1813
|
+
// È ciò che lo rende spaziale — la direzione indica una destinazione, e
|
|
1814
|
+
// con due soli pane un toggle sarebbe indistinguibile solo per caso.
|
|
1815
|
+
setFocus(key.leftArrow ? 'tasks' : 'sessions');
|
|
1807
1816
|
}
|
|
1808
1817
|
else if (key.upArrow) {
|
|
1809
1818
|
if (focus === 'tasks')
|
|
@@ -1880,7 +1889,7 @@ function Deck({ cwd, tasksPath, tasksDir }) {
|
|
|
1880
1889
|
// Vive solo sul pane sessioni: il fork ha per oggetto una conversazione,
|
|
1881
1890
|
// e senza focus lì non ce n'è una selezionata su cui agire.
|
|
1882
1891
|
if (focus !== 'sessions') {
|
|
1883
|
-
setNote('f → fork: seleziona una sessione (
|
|
1892
|
+
setNote('f → fork: seleziona una sessione (→ per il pane)');
|
|
1884
1893
|
}
|
|
1885
1894
|
else {
|
|
1886
1895
|
const s = selSessionObj;
|
|
@@ -1912,7 +1921,7 @@ function Deck({ cwd, tasksPath, tasksDir }) {
|
|
|
1912
1921
|
// pinnata STALE (l'unico modo di spinnarla). Scrive il sidecar e ricarica
|
|
1913
1922
|
// subito, senza attendere il tick del poll.
|
|
1914
1923
|
if (focus !== 'sessions') {
|
|
1915
|
-
setNote('p → pin: seleziona una sessione (
|
|
1924
|
+
setNote('p → pin: seleziona una sessione (→ per il pane)');
|
|
1916
1925
|
}
|
|
1917
1926
|
else if (!selSessionId) {
|
|
1918
1927
|
setNote('p → nessuna sessione da pinnare');
|
|
@@ -1940,7 +1949,7 @@ function Deck({ cwd, tasksPath, tasksDir }) {
|
|
|
1940
1949
|
// su una pinnata STALE, perché annotare «questa non c'è più, era X» è
|
|
1941
1950
|
// proprio il caso in cui una nota serve.
|
|
1942
1951
|
if (focus !== 'sessions') {
|
|
1943
|
-
setNote('N → nota: seleziona una sessione (
|
|
1952
|
+
setNote('N → nota: seleziona una sessione (→ per il pane)');
|
|
1944
1953
|
}
|
|
1945
1954
|
else if (!selSessionId) {
|
|
1946
1955
|
setNote('N → nessuna sessione da annotare');
|
|
@@ -1958,7 +1967,7 @@ function Deck({ cwd, tasksPath, tasksDir }) {
|
|
|
1958
1967
|
// il binding è nostro, il transcript è di CC — riassegnare una
|
|
1959
1968
|
// conversazione il cui transcript non c'è più resta legittimo.
|
|
1960
1969
|
if (focus !== 'sessions') {
|
|
1961
|
-
setNote('A → assegna: seleziona una sessione (
|
|
1970
|
+
setNote('A → assegna: seleziona una sessione (→ per il pane)');
|
|
1962
1971
|
}
|
|
1963
1972
|
else if (!selSessionId) {
|
|
1964
1973
|
setNote('A → nessuna sessione da assegnare');
|
|
@@ -2513,7 +2522,7 @@ function AssignScreen({ sessionId, label, current, filter, rows, selected, match
|
|
|
2513
2522
|
* segmento resta il primo a cedere il posto (`↑↓` in coda alle voci navigabili).
|
|
2514
2523
|
*
|
|
2515
2524
|
* T100 — la riga non è più informativa: le voci del catalogo sono SELEZIONABILI
|
|
2516
|
-
* con
|
|
2525
|
+
* con `tab`, e l'attiva si distingue in video inverso (D5 — costa 0 colonne e non
|
|
2517
2526
|
* entra in gara con la semantica di colore già occupata). Le voci ci sono tutte
|
|
2518
2527
|
* anche a 0 (D1): un catalogo che si accorcia sposta le voci sotto le dita.
|
|
2519
2528
|
* L'ordine è vincolato — le navigabili PRIMA di `↑N`/`↓N`, che cadono per primi
|
package/dist/pane-views.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// T100 — Catalogo delle viste dei due pane. L'header smette di essere una riga
|
|
2
2
|
// di contatori e diventa un SELETTORE: ogni segmento che nomina un sottoinsieme
|
|
3
3
|
// calcolabile (`nascoste`, `archiviabili`, `vive`, `📌`, `+più vecchie`) è una
|
|
4
|
-
// vista raggiungibile con
|
|
4
|
+
// vista raggiungibile con `tab`.
|
|
5
5
|
//
|
|
6
6
|
// Modulo PURO: nessun import da ink/react, nessun I/O. Il calcolo resta dove
|
|
7
7
|
// stava — `view.ts` per i filtri task, `session-list.ts` per l'assemblaggio a
|
package/package.json
CHANGED