14 KiB
mcp-hal9002 Test Report
Data: 15 marzo 2026 — aggiornato al 16 marzo 2026
Obiettivo
Tracciare gli scenari di test eseguiti sui tool MCP di mcp-hal9002, con esito, note operative e anomalie osservate. Questo documento viene aggiornato a ogni campagna di test significativa.
Ambito Coperto
Tool coperti durante le sessioni:
gui_status()open_gui()implicito tramiteopen_tab(...)close_gui()open_tab(...)list_tabs()focus_tab(...)exec_command(...)read_tab(...)read_last_command_result(...)wait_for_command(...)wait_for_running_command(...)wait_for_command_result(...)wait_for_prompt(...)capture_screenshot(...)close_tab(...)
Matrice Scenari
1. Lifecycle GUI (T1)
Stato iniziale verificato con GUI già in esecuzione e tab residue da test precedenti.
Scenari eseguiti:
- chiusura completa della GUI condivisa con
close_gui() - verifica di
running=falsedopoclose_gui() - riavvio implicito della GUI tramite
open_tab(...) - verifica del riuso dell'istanza condivisa via socket locale
gui_status()con GUI spenta →running=falsegui_status()con GUI attiva → campi geometria etab_countpresenti
Esito: PASS
Note:
- la GUI si spegne correttamente e il socket viene rimosso
- una nuova
open_tab(...)rilancia la GUI come previsto gui_status()non lancia la GUI — comportamento corretto
2. Lifecycle Tab (T2)
Scenari eseguiti:
- apertura di più tab con
titledifferenti - apertura di tab con
cwdesplicito - verifica elenco tab con
list_tabs() - cambio tab attiva con
focus_tab(...) - chiusura di una tab intermedia con
close_tab(...) - verifica consistenza degli ID residui dopo la chiusura
focus_tab(...)sutab_idinesistente → RuntimeError atteso
Esito: PASS
Note:
- gli ID tab restano coerenti dopo chiusure intermedie
- lo stato
activesegue correttamente la tab focalizzata - gli errori su
tab_idinesistente sono uniformi tra tutti i tool tab-scoped
3. Esecuzione Comandi con Auto Submit (T3)
Scenari eseguiti:
exec_command(tab_id, "pwd", auto_submit=True)su tab incwd=/home/enne2exec_command(tab_id, "pwd", auto_submit=True)su tab incwd=/home/enne2/dev/mcp-hal9002exec_command(tab_id, "whoami", auto_submit=True)exec_command(tab_id, "ls /definitely-missing-path", auto_submit=True)exec_command(tab_id, "uname -r", auto_submit=True)
Esito: PASS
Note:
auto_submit=Trueinvia il comando e attende solo la sua conclusione- il
cwdosservato nei risultati coincide con la directory della tab - gli errori runtime del comando (
exit_code=1) sono tracciati correttamente after_sequencerestituito è pronto per passare await_for_command_result
4. Pattern after_sequence (T4)
Scenari eseguiti:
- submit di
ls /tmpconauto_submit=True, salvataggio diafter_sequence - chiamata a
wait_for_command_result(tab_id, after_sequence=...)con il valore ottenuto - submit di un secondo comando e verifica che
after_sequencediverso isoli risultati separati
Esito: PASS
Note:
after_sequencepermette di isolare esattamente il comando appena emesso- i risultati includono
sequence,command,cwd,cwd_after,exit_code,duration_seconds,text - il campo
textcontiene l'output catturato tra i marker shell, pulito da prompt e echo
5. Lettura Output e Risultati (T5)
Scenari eseguiti:
- lettura scrollback grezzo con
read_tab(...)dopo unexec_command - lettura ultimo risultato tracciato con
read_last_command_result(...) - attesa del risultato con
wait_for_command_result(...) - confronto metadati tra
read_last_command_result(...)ewait_for_command_result(...) - distinzione uso:
read_tabper output grezzo,read_last_command_resultper metadati strutturati
Esito: PASS
Note:
read_tabrestituisce testo grezzo con prompt e echo: utile per debug e sessioni delegateread_last_command_resultfornisce output pulito tra i marker hook: utile per parsing strutturato- i due metodi convergono sugli stessi metadati per lo stesso comando completato
read_tabè l'unica opzione pratica nelle sessioni delegate dove i command events non vengono emessi
6. Attese e Timeout (T6)
Scenari eseguiti:
- pausa esplicita con
wait_for_command(delay_seconds=2.0) - timeout breve su comando lungo con
wait_for_running_command(tab_id, timeout=0.5)→ RuntimeError atteso wait_for_running_command(tab_id)su tab idle → RuntimeError "no tracked command is currently running"- attesa lunga di completamento sullo stesso comando in esecuzione
- attesa di risultato con
after_sequencecorretto sudu -ah /usr
Esito: PASS
Note:
wait_for_running_commandsu tab idle fallisce immediatamente come previsto- il timeout breve fallisce correttamente mentre il comando è ancora in corso
- l'attesa lunga porta al completamento atteso
wait_for_running_command(...)ewait_for_command_result(...)restituiscono metadati coerenti sullo stesso evento finale
7. Screenshot — Target e Naming (T7 / T8)
Scenari eseguiti:
- screenshot
target="window"con overlay diagnostico - screenshot
target="tab"con overlay diagnostico - screenshot
target="tab-container"con overlay diagnostico - entrambi
target="tab"etarget="tab-container"sullo stessotab_id, stesso secondo → collisione naming confermata - stesso scenario con
pathesplicito per ciascuna chiamata → nessuna collisione
Esito: PASS con anomalia nota (vedi Anomalia 1)
Note:
- la cattura funziona per tutti i target provati
- i metadata sidecar JSON risultano popolati correttamente
- la collisione di naming è riproducibile e confermata
- il workaround con
pathesplicito risolve completamente la collisione - il campo
summarynel risultato contiene path, dimensioni, tipo widget e renderer
8. Errori e Guardrail (T8)
Scenari eseguiti:
exec_command(..., auto_submit=True)con shell syntax bloccata:ls | headexec_command(..., auto_submit=True)con shell syntax bloccata:echo hi && echo byeexec_command(..., auto_submit=True)con comando vietato:python3 -c 'print(1)'exec_command(..., auto_submit=True)con comando non in whitelist:jq ...focus_tab(...)sutab_idinesistenteread_tab(...)sutab_idinesistenteclose_tab(...)sutab_idinesistente
Esito: PASS
Note:
- i messaggi d'errore sono coerenti con le regole dei guardrail
- gli errori vengono sollevati prima del submit, non dopo
- non sono emersi stati corrotti del terminale dopo gli errori lato tool
9. Comportamento open_tab(command=...) (T9)
Scenari eseguiti:
- apertura tab con
open_tab(command="uname -r")(comando terminante) - verifica con
read_last_command_result(...)dopo ~500 ms - apertura tab con
open_tab(command="bash --norc")(sub-shell persistente) - tentativo di
read_last_command_result(...)nella tab con sub-shell
Esito: PASS con distinzione critica
Note:
- comandi terminanti (
uname -r,ls /tmp, ecc.) iniettati viacommand=sono tracciati comesequence=1con i normali metadati command event - sub-shell persistenti (
bash,ssh,python3REPL) avviate viacommand=non sono tracciate: la sub-shell non eredita l'hook MCP, quindiread_last_command_resultsolleva RuntimeError - questa distinzione era documentata in modo errato nel docstring di
read_last_command_result— corretta durante il test
10. Submit Manuale (T11)
Scenari eseguiti:
exec_command(tab_id, "echo 'ciao dal test'", auto_submit=False)→ ritorno bloccante- utente preme Invio nella GUI dopo 2–3 secondi
- verifica che
exec_commandritornisubmitted_manually=true - verifica campo
newline_ignorednel risultato - chiamata a
wait_for_command_result(tab_id, after_sequence=...)sul risultato
Esito: PASS
Note:
exec_commandrimane in attesa bloccante fino a che l'utente non preme Invio nel terminale- il campo
submitted_manually=trueidentifica correttamente la modalità after_sequenceè disponibile anche in modalità manuale per filtrare il risultato attesonewline_ignored=falsein modalità manuale (il newline è parte dell'azione utente)
11. Attesa Comando Lungo con wait_for_running_command (T12)
Scenari eseguiti:
- utente digita e invia
sleep 4nella GUI manualmente - chiamata immediata a
wait_for_running_command(tab_id)dal tool - verifica che il tool attenda il completamento del sleep
- verifica metadati nel risultato:
duration_seconds≥ 4
Esito: PASS
Note:
wait_for_running_commandrileva correttamente lo statorunninge aspetta il completamento- il campo
duration_secondsriflette il tempo effettivo di esecuzione - questo scenario non ha
after_sequence, dimostrando il caso d'uso corretto diwait_for_running_command
12. Sessioni Delegate — in_delegated_session (T13 + S1–S7)
Questa sezione copre la sub-shell avviata manualmente e il flag in_delegated_session.
T13 — Primo scenario sub-shell manuale
Scenari eseguiti:
exec_command(tab_id, "bash --norc", auto_submit=False)con utente che preme Invio → sub-shell attiva- verifica che lo stato del tab diventi
interactive-session - iniezione di
echo testviaexec_command(tab_id, "echo test", auto_submit=False)nella sub-shell - verifica che la risposta contenga
in_delegated_session: true
Esito: PASS
Note:
- il flag
in_delegated_sessionè presente nella risposta sia perauto_submit=TruecheFalse - l'iniezione nella sub-shell funziona a livello VTE ma non produce command events tracciati
Campagna sub-shell S1–S7
Scenari eseguiti:
-
S1: apertura tab fresca, submit manuale di
bash --norcvia GUI Verifica:running_command_status(tab_id)riportastate="interactive-session"→PASS -
S2:
exec_command(tab_id, "echo test_s2", auto_submit=False)nella sub-shell attiva, utente preme Invio Verifica: risposta contienein_delegated_session: true→PASS -
S3:
read_tab(tab_id)sulla stessa tab Verifica: output VTE grezzo contienetest_s2→PASS -
S4:
wait_for_running_command(tab_id)→ RuntimeError immediato per statointeractive-sessionwait_for_command_result(tab_id, after_sequence=..., timeout=3)→ RuntimeError per timeout Verifica: entrambi falliscono come previsto; il percorso corretto èread_tab+wait_for_prompt→PASS -
S5: utente digita
exitnella sub-shell → ritorno alla shell parent MCPwait_for_prompt(tab_id, timeout=10)→ rilevamento del prompt parent Verifica:state="prompt",last_linecontiene il prompt della shell MCP →PASS -
S6:
exec_command(tab_id, "whoami", auto_submit=True)dopo exit dalla sub-shell Verifica: funziona normalmente,in_delegated_session: false→PASSNota: intervento manuale accidentale nella GUI ha aggiunto testo spurio, rimosso con Ctrl+C -
S7: pulizia —
close_tab(tab_id)Verifica: tab chiusa correttamente →PASS
Esito complessivo: PASS
Note tecniche:
- la GUI traccia le sub-shell in
TabStatecon campidelegated_session_* rpc_execingui.pyrilevastate="interactive-session"e impostapending_submit_in_delegated_session=True- il flag
in_delegated_sessionviene propagato in entrambi i path diexec_commandinserver.py wait_for_running_commandsolleva immediatamente perinteractive-session(comportamento corretto)wait_for_promptè il tool di osservazione raccomandato nelle sessioni delegate
Anomalie Osservate
1. Collisione Naming Screenshot
Stato: APERTA (workaround disponibile)
Sintomo:
- catture con
target="tab"etarget="tab-container"sullo stessotab_identro lo stesso secondo producono lo stesso path di default; la seconda sovrascrive la prima silenziosamente
Impatto:
- un file PNG o JSON può sovrascrivere l'altro
Workaround confermato:
- passare
pathesplicito a entrambe le chiamate risolve completamente il problema — verificato in T7/T8
Area coinvolta:
- generazione path di default screenshot in
gui.py
2. Tracciamento Startup Command Interattivi
Stato: PARZIALMENTE RISOLTA
Sintomo originale:
open_tab(command="bash")produceva output ma non rendeva osservabile il prompt né i command events
Aggiornamento post-T9:
- comandi terminanti (
uname -r,ls, ecc.) iniettati viaopen_tab(command=...)sono confermati come tracciati correttamente (sequence=1,exit_code=0) - sub-shell persistenti (
bash,python3 REPL,ssh) avviate viaopen_tab(command=...)rimangono non tracciate perché la sub-shell non eredita l'hook MCP
Impatto residuo:
- solo il caso sub-shell persistente via
open_tab(command=...)è ancora non tracciato - il caso più utile (sub-shell avviata via
exec_commandmanuale) è completamente supportato tramite il flagin_delegated_session+read_tab+wait_for_prompt
3. Timestamps di Esecuzione da Ricontrollare
Stato: APERTA (impatto basso in condizioni normali)
Sintomo:
- alcuni
started_ateduration_secondsosservati sembrano partire prima del submit effettivo percepito
Impatto:
- i metadati temporali potrebbero risultare meno affidabili del previsto nei report di comando
Area coinvolta:
- hook shell che scrive transcript ed eventi
Casi Ancora da Testare Manualmente
Tutti i casi elencati nella versione precedente di questo documento sono stati coperti:
exec_command(..., auto_submit=False)con modifica del comando → coperto in T11newline=Trueignorato in modalità manuale → confermato in T11 (newline_ignorednel risultato)- sessioni delegate (sub-shell, SSH) avviate con submit manuale → coperto in T13 + S1–S7
- uso combinato di
wait_for_prompt(...)ewait_for_running_command(...)in sessioni interattive → coperto in S4+S5
Nessun caso rilevante rimane da testare nelle condizioni attuali.
Stato Finale Ambiente di Test
Pulizia eseguita dopo ogni campagna:
- chiusura delle tab create per i test
- verifica finale con sola tab Home presente o GUI spenta
Esito cleanup: PASS per tutte le campagne
Conclusione
La maggior parte dei tool MCP testati risulta funzionante nei casi non interattivi e nei flussi standard di osservazione del terminale. Le sessioni delegate (sub-shell, SSH) sono ora supportate tramite il flag in_delegated_session nell'output di exec_command e l'uso combinato di read_tab + wait_for_prompt.
I problemi residui aperti sono due: la collisione di naming screenshot (workaround disponibile con path esplicito) e la piccola incertezza sui timestamp di esecuzione.