Clear extension errors after successful reload
- commit
- 1d11cc6766ccfe45a253614183f01951c4558eee
- author
- patriceckhart · · 2026-07-28 16:36 UTC
- parent
- fb1bc82
- signature
- unsigned
- refs
- tag: v0.3.17
3 files · +9 -4
M docs/extensions.md +5 -4
| @@ -645,10 +645,11 @@ done. Explicit `--ext` paths are remembered and reloaded alongside | |||
| 645 | 645 | discovered extensions. The temporary reload status reports each load | |
| 646 | 646 | error in red, including its message, and dismisses itself after five | |
| 647 | 647 | seconds. Extension failures from startup and `/reload-ext` remain in the | |
| 648 | - | scrolling chat until `/clear`, without being sent to the model or saved in | |
| 649 | - | the session transcript. Subprocess startup and handshake errors include the | |
| 650 | - | exact stderr log path for the failed extension. If a subprocess exits before | |
| 651 | - | sending `hello`, the error also reports its exit status or terminating signal. | |
| 648 | + | scrolling chat until a successful reload or `/clear`, without being sent to | |
| 649 | + | the model or saved in the session transcript. Subprocess startup and | |
| 650 | + | handshake errors include the exact stderr log path for the failed extension. | |
| 651 | + | If a subprocess exits before sending `hello`, the error also reports its exit | |
| 652 | + | status or terminating signal. | |
| 652 | 653 | ||
| 653 | 654 | ### TypeScript / Python | |
| 654 | 655 | ||
| @@ -645,10 +645,11 @@ done. Explicit `--ext` paths are remembered and reloaded alongside | |||||
| 645 | discovered extensions. The temporary reload status reports each load | 645 | discovered extensions. The temporary reload status reports each load | ||
| 646 | error in red, including its message, and dismisses itself after five | 646 | error in red, including its message, and dismisses itself after five | ||
| 647 | seconds. Extension failures from startup and `/reload-ext` remain in the | 647 | seconds. Extension failures from startup and `/reload-ext` remain in the | ||
| 648 | - | scrolling chat until `/clear`, without being sent to the model or saved in | 648 | + | scrolling chat until a successful reload or `/clear`, without being sent to |
| 649 | - | the session transcript. Subprocess startup and handshake errors include the | 649 | + | the model or saved in the session transcript. Subprocess startup and |
| 650 | - | exact stderr log path for the failed extension. If a subprocess exits before | 650 | + | handshake errors include the exact stderr log path for the failed extension. |
| 651 | - | sending `hello`, the error also reports its exit status or terminating signal. | 651 | + | If a subprocess exits before sending `hello`, the error also reports its exit |
| 652 | + | status or terminating signal. | |||
| 652 | 653 | ||||
| 653 | ### TypeScript / Python | 654 | ### TypeScript / Python | ||
| 654 | 655 | ||||
M packages/agent/modes/reload_ext.go +1 -0
| @@ -42,6 +42,7 @@ func (i *Interactive) setReloadStatus(msg string, failed bool) uint64 { | |||
| 42 | 42 | } | |
| 43 | 43 | i.statusOK = msg | |
| 44 | 44 | i.statusErr = "" | |
| 45 | + | i.reloadErrors = nil | |
| 45 | 46 | return i.reloadStatusSeq | |
| 46 | 47 | } | |
| 47 | 48 | ||
| @@ -42,6 +42,7 @@ func (i *Interactive) setReloadStatus(msg string, failed bool) uint64 { | |||||
| 42 | } | 42 | } | ||
| 43 | i.statusOK = msg | 43 | i.statusOK = msg | ||
| 44 | i.statusErr = "" | 44 | i.statusErr = "" | ||
| 45 | + | i.reloadErrors = nil | |||
| 45 | return i.reloadStatusSeq | 46 | return i.reloadStatusSeq | ||
| 46 | } | 47 | } | ||
| 47 | 48 | ||||
M packages/agent/modes/reload_ext_test.go +3 -0
| @@ -58,6 +58,9 @@ func TestSetReloadStatusUsesErrorChannelForFailures(t *testing.T) { | |||
| 58 | 58 | if i.statusOK != "reload complete" || i.statusErr != "" { | |
| 59 | 59 | t.Fatalf("successful reload status used wrong channel: err=%q ok=%q", i.statusErr, i.statusOK) | |
| 60 | 60 | } | |
| 61 | + | if len(i.reloadErrors) != 0 { | |
| 62 | + | t.Fatalf("reload errors = %q after successful reload, want none", i.reloadErrors) | |
| 63 | + | } | |
| 61 | 64 | } | |
| 62 | 65 | ||
| 63 | 66 | func TestStartupExtensionFailureAppearsInChatWithoutEnteringContext(t *testing.T) { | |
| @@ -58,6 +58,9 @@ func TestSetReloadStatusUsesErrorChannelForFailures(t *testing.T) { | |||||
| 58 | if i.statusOK != "reload complete" || i.statusErr != "" { | 58 | if i.statusOK != "reload complete" || i.statusErr != "" { | ||
| 59 | t.Fatalf("successful reload status used wrong channel: err=%q ok=%q", i.statusErr, i.statusOK) | 59 | t.Fatalf("successful reload status used wrong channel: err=%q ok=%q", i.statusErr, i.statusOK) | ||
| 60 | } | 60 | } | ||
| 61 | + | if len(i.reloadErrors) != 0 { | |||
| 62 | + | t.Fatalf("reload errors = %q after successful reload, want none", i.reloadErrors) | |||
| 63 | + | } | |||
| 61 | } | 64 | } | ||
| 62 | 65 | ||||
| 63 | func TestStartupExtensionFailureAppearsInChatWithoutEnteringContext(t *testing.T) { | 66 | func TestStartupExtensionFailureAppearsInChatWithoutEnteringContext(t *testing.T) { | ||