on main help sign in
Merge branch 'main' into ui
commitd334355ecb550fd1a60d92c2f4365d1d6ab96693 authorAyman Bagabas <ayman.bagabas@gmail.com> dateTue 20 Jan 2026, 09:46 (9 months ago) parent8ded0be4403170
11 files changed+29−40
.github/workflows/build.yml+1−1 .github/workflows/schema-update.yml+1−1 .github/workflows/security.yml+6−6 internal/app/app.go+8−1 internal/env/env.go+1−12 internal/env/env_test.go+4−2 internal/lsp/client.go+1−1 internal/message/message.go+5−5 internal/pubsub/broker.go+1−3 internal/pubsub/events.go−7 internal/tui/tui.go+1−1
.github/workflows/build.yml+1−1
@@ -18,7 +18,7 @@ jobs:
1818 - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
1919 with:
2020 persist-credentials: false
21− - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
21+ - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
2222 with:
2323 go-version-file: go.mod
2424 - run: go mod tidy
.github/workflows/schema-update.yml+1−1
@@ -14,7 +14,7 @@ jobs:
1414 - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
1515 with:
1616 token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
17− - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
17+ - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
1818 with:
1919 go-version-file: go.mod
2020 - run: go run . schema > ./schema.json
.github/workflows/security.yml+6−6
@@ -30,11 +30,11 @@ jobs:
3030 - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
3131 with:
3232 persist-credentials: false
33− - uses: github/codeql-action/init@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7
33+ - uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
3434 with:
3535 languages: ${{ matrix.language }}
36− - uses: github/codeql-action/autobuild@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7
37− - uses: github/codeql-action/analyze@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7
36+ - uses: github/codeql-action/autobuild@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
37+ - uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
3838
3939 grype:
4040 runs-on: ubuntu-latest
@@ -46,13 +46,13 @@ jobs:
4646 - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
4747 with:
4848 persist-credentials: false
49− - uses: anchore/scan-action@40a61b52209e9d50e87917c5b901783d546b12d0 # v7.2.1
49+ - uses: anchore/scan-action@62b74fb7bb810d2c45b1865f47a77655621862a5 # v7.2.3
5050 id: scan
5151 with:
5252 path: "."
5353 fail-build: true
5454 severity-cutoff: critical
55− - uses: github/codeql-action/upload-sarif@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7
55+ - uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
5656 with:
5757 sarif_file: ${{ steps.scan.outputs.sarif }}
5858
@@ -73,7 +73,7 @@ jobs:
7373 - name: Run govulncheck
7474 run: |
7575 govulncheck -C . -format sarif ./... > results.sarif
76− - uses: github/codeql-action/upload-sarif@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7
76+ - uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
7777 with:
7878 sarif_file: results.sarif
7979
internal/app/app.go+8−1
@@ -40,6 +40,13 @@ import (
4040 "github.com/charmbracelet/x/term"
4141)
4242
43+// UpdateAvailableMsg is sent when a new version is available.
44+type UpdateAvailableMsg struct {
45+ CurrentVersion string
46+ LatestVersion string
47+ IsDevelopment bool
48+}
49+
4350type App struct {
4451 Sessions session.Service
4552 Messages message.Service
@@ -452,7 +459,7 @@ func (app *App) checkForUpdates(ctx context.Context) {
452459 if err != nil || !info.Available() {
453460 return
454461 }
455− app.events <- pubsub.UpdateAvailableMsg{
462+ app.events <- UpdateAvailableMsg{
456463 CurrentVersion: info.Current,
457464 LatestVersion: info.Latest,
458465 IsDevelopment: info.IsDevelopment(),
internal/env/env.go+1−12
@@ -2,7 +2,6 @@ package env
22
33import (
44 "os"
5− "testing"
65)
76
87type Env interface {
@@ -18,17 +17,10 @@ func (o *osEnv) Get(key string) string {
1817}
1918
2019func (o *osEnv) Env() []string {
21− env := os.Environ()
22− if len(env) == 0 {
23− return nil
24− }
25− return env
20+ return os.Environ()
2621}
2722
2823func New() Env {
29− if testing.Testing() {
30− return NewFromMap(nil)
31− }
3224 return &osEnv{}
3325}
3426
@@ -46,9 +38,6 @@ func (m *mapEnv) Get(key string) string {
4638
4739// Env implements Env.
4840func (m *mapEnv) Env() []string {
49− if len(m.m) == 0 {
50− return nil
51− }
5241 env := make([]string, 0, len(m.m))
5342 for k, v := range m.m {
5443 env = append(env, k+"="+v)
internal/env/env_test.go+4−2
@@ -90,13 +90,15 @@ func TestMapEnv_Env(t *testing.T) {
9090 t.Run("empty map", func(t *testing.T) {
9191 env := NewFromMap(map[string]string{})
9292 envVars := env.Env()
93− require.Nil(t, envVars)
93+ require.NotNil(t, envVars)
94+ require.Len(t, envVars, 0)
9495 })
9596
9697 t.Run("nil map", func(t *testing.T) {
9798 env := NewFromMap(nil)
9899 envVars := env.Env()
99− require.Nil(t, envVars)
100+ require.NotNil(t, envVars)
101+ require.Len(t, envVars, 0)
100102 })
101103}
102104
internal/lsp/client.go+1−1
@@ -345,7 +345,7 @@ func (c *Client) CloseAllFiles(ctx context.Context) {
345345 slog.Debug("Closing file", "file", uri)
346346 }
347347 if err := c.client.NotifyDidCloseTextDocument(ctx, uri); err != nil {
348− slog.Warn("Error closing rile", "uri", uri, "error", err)
348+ slog.Warn("Error closing file", "uri", uri, "error", err)
349349 continue
350350 }
351351 c.openFiles.Del(uri)
internal/message/message.go+5−5
@@ -63,7 +63,7 @@ func (s *service) Create(ctx context.Context, sessionID string, params CreateMes
6363 Reason: "stop",
6464 })
6565 }
66− partsJSON, err := marshallParts(params.Parts)
66+ partsJSON, err := marshalParts(params.Parts)
6767 if err != nil {
6868 return Message{}, err
6969 }
@@ -110,7 +110,7 @@ func (s *service) DeleteSessionMessages(ctx context.Context, sessionID string) e
110110}
111111
112112func (s *service) Update(ctx context.Context, message Message) error {
113− parts, err := marshallParts(message.Parts)
113+ parts, err := marshalParts(message.Parts)
114114 if err != nil {
115115 return err
116116 }
@@ -158,7 +158,7 @@ func (s *service) List(ctx context.Context, sessionID string) ([]Message, error)
158158}
159159
160160func (s *service) fromDBItem(item db.Message) (Message, error) {
161− parts, err := unmarshallParts([]byte(item.Parts))
161+ parts, err := unmarshalParts([]byte(item.Parts))
162162 if err != nil {
163163 return Message{}, err
164164 }
@@ -192,7 +192,7 @@ type partWrapper struct {
192192 Data ContentPart `json:"data"`
193193}
194194
195−func marshallParts(parts []ContentPart) ([]byte, error) {
195+func marshalParts(parts []ContentPart) ([]byte, error) {
196196 wrappedParts := make([]partWrapper, len(parts))
197197
198198 for i, part := range parts {
@@ -225,7 +225,7 @@ func marshallParts(parts []ContentPart) ([]byte, error) {
225225 return json.Marshal(wrappedParts)
226226}
227227
228−func unmarshallParts(data []byte) ([]ContentPart, error) {
228+func unmarshalParts(data []byte) ([]ContentPart, error) {
229229 temp := []json.RawMessage{}
230230
231231 if err := json.Unmarshal(data, &temp); err != nil {
internal/pubsub/broker.go+1−3
@@ -20,13 +20,11 @@ func NewBroker[T any]() *Broker[T] {
2020}
2121
2222func NewBrokerWithOptions[T any](channelBufferSize, maxEvents int) *Broker[T] {
23− b := &Broker[T]{
23+ return &Broker[T]{
2424 subs: make(map[chan Event[T]]struct{}),
2525 done: make(chan struct{}),
26− subCount: 0,
2726 maxEvents: maxEvents,
2827 }
29− return b
3028}
3129
3230func (b *Broker[T]) Shutdown() {
internal/pubsub/events.go−7
@@ -26,10 +26,3 @@ type (
2626 Publish(EventType, T)
2727 }
2828)
29−
30−// UpdateAvailableMsg is sent when a new version is available.
31−type UpdateAvailableMsg struct {
32− CurrentVersion string
33− LatestVersion string
34− IsDevelopment bool
35−}
internal/tui/tui.go+1−1
@@ -385,7 +385,7 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
385385 }
386386 return a, tea.Batch(cmds...)
387387 // Update Available
388− case pubsub.UpdateAvailableMsg:
388+ case app.UpdateAvailableMsg:
389389 // Show update notification in status bar
390390 statusMsg := fmt.Sprintf("Crush update available: v%s → v%s.", msg.CurrentVersion, msg.LatestVersion)
391391 if msg.IsDevelopment {