detached 84a8a0c

Plan shared download runtime cleanup

Agent-Logs-Url: https://github.com/bnema/dumber/sessions/1efb54e2-29d8-4b77-924a-ea1cf2cfa5ec

Co-authored-by: bnema <5212137+bnema@users.noreply.github.com>
commit
84a8a0cd90d1b0cc1b5e63ee459116adece827a3
author
copilot-swe-agent[bot] · · 2026-04-14 13:01 UTC
committer
brice · · 2026-04-19 19:06 UTC
parent
533930e
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
4 files · +22 -21
M internal/infrastructure/cef/download_handler.go +1 -1
@@ -144,7 +144,7 @@ func (h *downloadHandler) onDownloadUpdated(
144144 }
145145 err := fmt.Errorf("download failed: %s", state.filename)
146146 if downloadItem.IsInterrupted() {
147- err = fmt.Errorf("download interrupted: %s (%s)", state.filename, downloadItem.GetInterruptReason())
147+ err = fmt.Errorf("download interrupted: %s (%v)", state.filename, downloadItem.GetInterruptReason())
148148 } else if downloadItem.IsCanceled() {
149149 err = fmt.Errorf("download canceled: %s", state.filename)
150150 }
@@ -144,7 +144,7 @@ func (h *downloadHandler) onDownloadUpdated(
144 }144 }
145 err := fmt.Errorf("download failed: %s", state.filename)145 err := fmt.Errorf("download failed: %s", state.filename)
146 if downloadItem.IsInterrupted() {146 if downloadItem.IsInterrupted() {
147- err = fmt.Errorf("download interrupted: %s (%s)", state.filename, downloadItem.GetInterruptReason())147+ err = fmt.Errorf("download interrupted: %s (%v)", state.filename, downloadItem.GetInterruptReason())
148 } else if downloadItem.IsCanceled() {148 } else if downloadItem.IsCanceled() {
149 err = fmt.Errorf("download canceled: %s", state.filename)149 err = fmt.Errorf("download canceled: %s", state.filename)
150 }150 }
M internal/infrastructure/cef/download_handler_test.go +19 -19
@@ -21,28 +21,28 @@ type stubDownloadItem struct {
2121 canceled bool
2222 }
2323
24-func (s stubDownloadItem) IsValid() bool { return true }
25-func (s stubDownloadItem) IsInProgress() bool { return !s.complete && !s.canceled }
26-func (s stubDownloadItem) IsComplete() bool { return s.complete }
27-func (s stubDownloadItem) IsCanceled() bool { return s.canceled }
28-func (s stubDownloadItem) IsInterrupted() bool { return false }
24+func (s stubDownloadItem) IsValid() bool { return true }
25+func (s stubDownloadItem) IsInProgress() bool { return !s.complete && !s.canceled }
26+func (s stubDownloadItem) IsComplete() bool { return s.complete }
27+func (s stubDownloadItem) IsCanceled() bool { return s.canceled }
28+func (s stubDownloadItem) IsInterrupted() bool { return false }
2929 func (s stubDownloadItem) GetInterruptReason() purecef.DownloadInterruptReason {
3030 return 0
3131 }
32-func (s stubDownloadItem) GetCurrentSpeed() int64 { return 0 }
33-func (s stubDownloadItem) GetPercentComplete() int32 { return 0 }
34-func (s stubDownloadItem) GetTotalBytes() int64 { return 0 }
35-func (s stubDownloadItem) GetReceivedBytes() int64 { return 0 }
36-func (s stubDownloadItem) GetStartTime() uintptr { return 0 }
37-func (s stubDownloadItem) GetEndTime() uintptr { return 0 }
38-func (s stubDownloadItem) GetFullPath() string { return s.fullPath }
39-func (s stubDownloadItem) GetID() uint32 { return s.id }
40-func (s stubDownloadItem) GetURL() string { return s.url }
41-func (s stubDownloadItem) GetOriginalURL() string { return s.url }
42-func (s stubDownloadItem) GetSuggestedFileName() string { return s.suggested }
43-func (s stubDownloadItem) GetContentDisposition() string { return "" }
44-func (s stubDownloadItem) GetMimeType() string { return s.mimeType }
45-func (s stubDownloadItem) IsPaused() bool { return false }
32+func (s stubDownloadItem) GetCurrentSpeed() int64 { return 0 }
33+func (s stubDownloadItem) GetPercentComplete() int32 { return 0 }
34+func (s stubDownloadItem) GetTotalBytes() int64 { return 0 }
35+func (s stubDownloadItem) GetReceivedBytes() int64 { return 0 }
36+func (s stubDownloadItem) GetStartTime() uintptr { return 0 }
37+func (s stubDownloadItem) GetEndTime() uintptr { return 0 }
38+func (s stubDownloadItem) GetFullPath() string { return s.fullPath }
39+func (s stubDownloadItem) GetID() uint32 { return s.id }
40+func (s stubDownloadItem) GetURL() string { return s.url }
41+func (s stubDownloadItem) GetOriginalURL() string { return s.url }
42+func (s stubDownloadItem) GetSuggestedFileName() string { return s.suggested }
43+func (s stubDownloadItem) GetContentDisposition() string { return "" }
44+func (s stubDownloadItem) GetMimeType() string { return s.mimeType }
45+func (s stubDownloadItem) IsPaused() bool { return false }
4646
4747 type stubBeforeDownloadCallback struct {
4848 path string
@@ -21,28 +21,28 @@ type stubDownloadItem struct {
21 canceled bool21 canceled bool
22 }22 }
23 23
24-func (s stubDownloadItem) IsValid() bool { return true }24+func (s stubDownloadItem) IsValid() bool { return true }
25-func (s stubDownloadItem) IsInProgress() bool { return !s.complete && !s.canceled }25+func (s stubDownloadItem) IsInProgress() bool { return !s.complete && !s.canceled }
26-func (s stubDownloadItem) IsComplete() bool { return s.complete }26+func (s stubDownloadItem) IsComplete() bool { return s.complete }
27-func (s stubDownloadItem) IsCanceled() bool { return s.canceled }27+func (s stubDownloadItem) IsCanceled() bool { return s.canceled }
28-func (s stubDownloadItem) IsInterrupted() bool { return false }28+func (s stubDownloadItem) IsInterrupted() bool { return false }
29 func (s stubDownloadItem) GetInterruptReason() purecef.DownloadInterruptReason {29 func (s stubDownloadItem) GetInterruptReason() purecef.DownloadInterruptReason {
30 return 030 return 0
31 }31 }
32-func (s stubDownloadItem) GetCurrentSpeed() int64 { return 0 }32+func (s stubDownloadItem) GetCurrentSpeed() int64 { return 0 }
33-func (s stubDownloadItem) GetPercentComplete() int32 { return 0 }33+func (s stubDownloadItem) GetPercentComplete() int32 { return 0 }
34-func (s stubDownloadItem) GetTotalBytes() int64 { return 0 }34+func (s stubDownloadItem) GetTotalBytes() int64 { return 0 }
35-func (s stubDownloadItem) GetReceivedBytes() int64 { return 0 }35+func (s stubDownloadItem) GetReceivedBytes() int64 { return 0 }
36-func (s stubDownloadItem) GetStartTime() uintptr { return 0 }36+func (s stubDownloadItem) GetStartTime() uintptr { return 0 }
37-func (s stubDownloadItem) GetEndTime() uintptr { return 0 }37+func (s stubDownloadItem) GetEndTime() uintptr { return 0 }
38-func (s stubDownloadItem) GetFullPath() string { return s.fullPath }38+func (s stubDownloadItem) GetFullPath() string { return s.fullPath }
39-func (s stubDownloadItem) GetID() uint32 { return s.id }39+func (s stubDownloadItem) GetID() uint32 { return s.id }
40-func (s stubDownloadItem) GetURL() string { return s.url }40+func (s stubDownloadItem) GetURL() string { return s.url }
41-func (s stubDownloadItem) GetOriginalURL() string { return s.url }41+func (s stubDownloadItem) GetOriginalURL() string { return s.url }
42-func (s stubDownloadItem) GetSuggestedFileName() string { return s.suggested }42+func (s stubDownloadItem) GetSuggestedFileName() string { return s.suggested }
43-func (s stubDownloadItem) GetContentDisposition() string { return "" }43+func (s stubDownloadItem) GetContentDisposition() string { return "" }
44-func (s stubDownloadItem) GetMimeType() string { return s.mimeType }44+func (s stubDownloadItem) GetMimeType() string { return s.mimeType }
45-func (s stubDownloadItem) IsPaused() bool { return false }45+func (s stubDownloadItem) IsPaused() bool { return false }
46 46
47 type stubBeforeDownloadCallback struct {47 type stubBeforeDownloadCallback struct {
48 path string48 path string
M internal/infrastructure/cef/webview_handlers_test.go +1 -1
@@ -6,9 +6,9 @@ import (
66 "testing"
77 "time"
88
9+ "github.com/bnema/dumber/internal/application/usecase"
910 purecef "github.com/bnema/purego-cef/cef"
1011 cefmocks "github.com/bnema/purego-cef/cef/mocks"
11- "github.com/bnema/dumber/internal/application/usecase"
1212 "github.com/stretchr/testify/assert"
1313 "github.com/stretchr/testify/mock"
1414 "github.com/stretchr/testify/require"
@@ -6,9 +6,9 @@ import (
6 "testing"6 "testing"
7 "time"7 "time"
8 8
9+ "github.com/bnema/dumber/internal/application/usecase"
9 purecef "github.com/bnema/purego-cef/cef"10 purecef "github.com/bnema/purego-cef/cef"
10 cefmocks "github.com/bnema/purego-cef/cef/mocks"11 cefmocks "github.com/bnema/purego-cef/cef/mocks"
11- "github.com/bnema/dumber/internal/application/usecase"
12 "github.com/stretchr/testify/assert"12 "github.com/stretchr/testify/assert"
13 "github.com/stretchr/testify/mock"13 "github.com/stretchr/testify/mock"
14 "github.com/stretchr/testify/require"14 "github.com/stretchr/testify/require"
M internal/infrastructure/webkit/webview.go +1 -0
@@ -3,6 +3,7 @@ package webkit
33 import (
44 "context"
55 "fmt"
6+ "net/url"
67 "os"
78 "strings"
89 "sync"
@@ -3,6 +3,7 @@ package webkit
3 import (3 import (
4 "context"4 "context"
5 "fmt"5 "fmt"
6+ "net/url"
6 "os"7 "os"
7 "strings"8 "strings"
8 "sync"9 "sync"

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close