mirror of
https://github.com/lukaszraczylo/ghtracker.git
synced 2026-10-12 00:45:38 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d65fed1546 | ||
|
|
4b9b6303de | ||
|
|
021dc2e8f9 | ||
|
|
fb31e31bec | ||
|
|
0585326fea | ||
|
|
5bca4c38f0 | ||
|
|
eff9559aee | ||
|
|
5c5416f6f0 | ||
|
|
a0fd6d6856 | ||
|
|
ac5eb2f16a | ||
|
|
66ed84bdbf | ||
|
|
e6f28a223a | ||
|
|
0a2469ef7d | ||
|
|
06922abe05 | ||
|
|
2100458973 |
@@ -17,11 +17,11 @@ Release archives and the image checksums are signed with cosign.
|
|||||||
The dashboard lists only what needs attention, grouped by project. The project with the newest problem comes first:
|
The dashboard lists only what needs attention, grouped by project. The project with the newest problem comes first:
|
||||||
|
|
||||||
- Failing workflows, including scheduled and other background ones, with a link to the run.
|
- Failing workflows, including scheduled and other background ones, with a link to the run.
|
||||||
- Pull requests that wait too long or fail their checks, with links and age.
|
- Pull requests, one line each: new ones (`pr_fresh`), ones that wait too long (`pr_waiting`) and ones that fail their checks.
|
||||||
- Stale issues, as one line per project.
|
- Open issues, one line each: new ones (`issue_fresh`) and ones without recent activity (`issue_stale`).
|
||||||
- Projects that failed to refresh, or loaded only in part.
|
- Projects that failed to refresh, or loaded only in part.
|
||||||
|
|
||||||
A side panel lists every project with its latest release (or newest tag), a link to the release, and counts of workflows, open pull requests and issues. Healthy items do not appear anywhere else.
|
A side panel lists every project with its latest release (or newest tag), a link to the release, and counts of workflows, open pull requests and issues. Every open non-draft pull request and every open issue raises a warning, so a project with open work is never green.
|
||||||
|
|
||||||
### Search and filters
|
### Search and filters
|
||||||
|
|
||||||
@@ -48,7 +48,9 @@ A side panel lists every project with its latest release (or newest tag), a link
|
|||||||
| Non-draft PR open longer than `pr_warn_after` | warn |
|
| Non-draft PR open longer than `pr_warn_after` | warn |
|
||||||
| PR checks failing | warn |
|
| PR checks failing | warn |
|
||||||
| Workflow queued or running longer than `workflow_stuck_after` | warn |
|
| Workflow queued or running longer than `workflow_stuck_after` | warn |
|
||||||
| Open issues without activity for `issue_stale_after` (one alert per repo) | warn |
|
| Non-draft PR open less than `pr_warn_after` (`pr_fresh`) | warn |
|
||||||
|
| Open issue without activity for `issue_stale_after` (`issue_stale`, one alert per issue) | warn |
|
||||||
|
| Open issue with recent activity (`issue_fresh`, one alert per issue) | warn |
|
||||||
| A section failed to load, for example a missing App permission | warn |
|
| A section failed to load, for example a missing App permission | warn |
|
||||||
| Data older than `data_stale_after` | warn |
|
| Data older than `data_stale_after` | warn |
|
||||||
|
|
||||||
@@ -122,7 +124,7 @@ actions:
|
|||||||
All metrics use the `ghtracker_` prefix. Gauges are computed at scrape time.
|
All metrics use the `ghtracker_` prefix. Gauges are computed at scrape time.
|
||||||
|
|
||||||
| Metric | Labels |
|
| Metric | Labels |
|
||||||
| -------------------------------------------------------------------------------------------------------------- | -------------------------- |
|
| ----------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
|
||||||
| `repo_up`, `repo_health` (0 ok, 1 warn, 2 crit) | repo |
|
| `repo_up`, `repo_health` (0 ok, 1 warn, 2 crit) | repo |
|
||||||
| `repo_open_issues`, `repo_open_prs`, `repo_open_prs_failing_checks`, `repo_stale_issues` | repo |
|
| `repo_open_issues`, `repo_open_prs`, `repo_open_prs_failing_checks`, `repo_stale_issues` | repo |
|
||||||
| `repo_oldest_pr_age_seconds`, `repo_last_refresh_timestamp_seconds` | repo |
|
| `repo_oldest_pr_age_seconds`, `repo_last_refresh_timestamp_seconds` | repo |
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ module github.com/lukaszraczylo/ghtracker
|
|||||||
go 1.26.0
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/prometheus/client_golang v1.24.1
|
github.com/prometheus/client_golang v1.25.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,6 +15,6 @@ require (
|
|||||||
github.com/prometheus/client_model v0.6.3 // indirect
|
github.com/prometheus/client_model v0.6.3 // indirect
|
||||||
github.com/prometheus/common v0.72.0 // indirect
|
github.com/prometheus/common v0.72.0 // indirect
|
||||||
github.com/prometheus/procfs v0.22.0 // indirect
|
github.com/prometheus/procfs v0.22.0 // indirect
|
||||||
golang.org/x/sys v0.48.0 // indirect
|
golang.org/x/sys v0.49.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.12 // indirect
|
google.golang.org/protobuf v1.36.12 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
|
|||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk=
|
github.com/klauspost/compress v1.20.1 h1:T7kKElXUMXrUJ2E9QhQhxFtcK5rPyLdsGZvdbLMPdiQ=
|
||||||
github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
github.com/klauspost/compress v1.20.1/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI=
|
||||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/prometheus/client_golang v1.24.1 h1:JnJkREXzWxUdCuPFpIWZiPispT9xVV59uiuyR2bPlnU=
|
github.com/prometheus/client_golang v1.25.0 h1:cDtW1TcFsMi1RJc8khwCKB4VhzwV04aKqbYtNOXuiK0=
|
||||||
github.com/prometheus/client_golang v1.24.1/go.mod h1:F+oSRECHg4sse5ucfYpYDeIv/hu68Zo0uoHKetWnzcE=
|
github.com/prometheus/client_golang v1.25.0/go.mod h1:j2X/4/kaQHLPnmyEU8zjmkndo1T317VpCIQEml8LTKk=
|
||||||
github.com/prometheus/client_model v0.6.3 h1:O0jaTVAYNxTHYInEPFJt5I3+sN8zqBtVMPTB1qyxiEo=
|
github.com/prometheus/client_model v0.6.3 h1:O0jaTVAYNxTHYInEPFJt5I3+sN8zqBtVMPTB1qyxiEo=
|
||||||
github.com/prometheus/client_model v0.6.3/go.mod h1:gpN5P9S7Rr6Yr92PiQ+Ixvhf6JZEkF1dnxsYL2aPBEM=
|
github.com/prometheus/client_model v0.6.3/go.mod h1:gpN5P9S7Rr6Yr92PiQ+Ixvhf6JZEkF1dnxsYL2aPBEM=
|
||||||
github.com/prometheus/common v0.72.0 h1:tAYsE+sPJxIncDAobm4H5aQjmox9ZxEIIqPbiffa8G4=
|
github.com/prometheus/common v0.72.0 h1:tAYsE+sPJxIncDAobm4H5aQjmox9ZxEIIqPbiffa8G4=
|
||||||
@@ -26,8 +26,8 @@ go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ=
|
|||||||
go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ=
|
go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ=
|
||||||
go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
|
go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
|
||||||
go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
|
go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
|
||||||
golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
|
golang.org/x/sys v0.49.0 h1:XbzkgYJHdqh/8m2Uu0W/dQv8nktxx4BFHp1M0gROTXA=
|
||||||
golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
|
golang.org/x/sys v0.49.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
|
||||||
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
|
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
|
||||||
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
|||||||
@@ -155,25 +155,25 @@ func (c *Collector) Refresh(ctx context.Context) {
|
|||||||
c.limited.Store(false)
|
c.limited.Store(false)
|
||||||
c.scanDone.Store(0)
|
c.scanDone.Store(0)
|
||||||
c.scanTotal.Store(int64(len(c.names)))
|
c.scanTotal.Store(int64(len(c.names)))
|
||||||
results := make([]model.Repo, len(c.names))
|
|
||||||
sem := make(chan struct{}, c.concurrency)
|
sem := make(chan struct{}, c.concurrency)
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
for i, name := range c.names {
|
for _, name := range c.names {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
sem <- struct{}{}
|
sem <- struct{}{}
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
defer func() { <-sem }()
|
defer func() { <-sem }()
|
||||||
results[i] = c.refreshOne(ctx, name, start, true)
|
r := c.refreshOne(ctx, name, start, true)
|
||||||
|
// Publish per repo so a running scan shows new and resolved alerts as they land.
|
||||||
|
c.mu.Lock()
|
||||||
|
c.repos[r.FullName] = r
|
||||||
|
c.mu.Unlock()
|
||||||
c.scanDone.Add(1)
|
c.scanDone.Add(1)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
for _, r := range results {
|
|
||||||
c.repos[r.FullName] = r
|
|
||||||
}
|
|
||||||
c.lastRefresh = start
|
c.lastRefresh = start
|
||||||
c.lastDur = c.now().Sub(start)
|
c.lastDur = c.now().Sub(start)
|
||||||
c.loaded = true
|
c.loaded = true
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ func TestEvaluate(t *testing.T) {
|
|||||||
}, map[string]model.Severity{KindWorkflowStuck: model.Warn}, model.Warn},
|
}, map[string]model.Severity{KindWorkflowStuck: model.Warn}, model.Warn},
|
||||||
"pr fresh": {func(r *model.Repo) {
|
"pr fresh": {func(r *model.Repo) {
|
||||||
r.PRs = []model.PullRequest{{Number: 1, Fork: true, CreatedAt: t0.Add(-47 * time.Hour)}}
|
r.PRs = []model.PullRequest{{Number: 1, Fork: true, CreatedAt: t0.Add(-47 * time.Hour)}}
|
||||||
}, map[string]model.Severity{}, model.OK},
|
}, map[string]model.Severity{KindPRFresh: model.Warn}, model.Warn},
|
||||||
"pr waiting warn": {func(r *model.Repo) {
|
"pr waiting warn": {func(r *model.Repo) {
|
||||||
r.PRs = []model.PullRequest{{Number: 1, Fork: true, CreatedAt: t0.Add(-49 * time.Hour)}}
|
r.PRs = []model.PullRequest{{Number: 1, Fork: true, CreatedAt: t0.Add(-49 * time.Hour)}}
|
||||||
}, map[string]model.Severity{KindPRWaiting: model.Warn}, model.Warn},
|
}, map[string]model.Severity{KindPRWaiting: model.Warn}, model.Warn},
|
||||||
@@ -79,11 +79,13 @@ func TestEvaluate(t *testing.T) {
|
|||||||
}, map[string]model.Severity{}, model.OK},
|
}, map[string]model.Severity{}, model.OK},
|
||||||
"pr checks failing": {func(r *model.Repo) {
|
"pr checks failing": {func(r *model.Repo) {
|
||||||
r.PRs = []model.PullRequest{{Number: 1, Fork: true, CreatedAt: t0, Checks: model.CheckSummary{State: model.ChecksFail, Failing: []string{"build"}}}}
|
r.PRs = []model.PullRequest{{Number: 1, Fork: true, CreatedAt: t0, Checks: model.CheckSummary{State: model.ChecksFail, Failing: []string{"build"}}}}
|
||||||
}, map[string]model.Severity{KindPRChecks: model.Warn}, model.Warn},
|
}, map[string]model.Severity{KindPRFresh: model.Warn, KindPRChecks: model.Warn}, model.Warn},
|
||||||
"issues stale aggregated": {func(r *model.Repo) {
|
"issue stale": {func(r *model.Repo) {
|
||||||
old := t0.Add(-40 * 24 * time.Hour)
|
r.Issues = []model.Issue{{Number: 1, CreatedAt: t0.Add(-60 * 24 * time.Hour), UpdatedAt: t0.Add(-40 * 24 * time.Hour)}}
|
||||||
r.Issues = []model.Issue{{Number: 1, UpdatedAt: old}, {Number: 2, UpdatedAt: old}, {Number: 3, UpdatedAt: t0}}
|
}, map[string]model.Severity{KindIssueStale: model.Warn}, model.Warn},
|
||||||
}, map[string]model.Severity{KindIssuesStale: model.Warn}, model.Warn},
|
"issue fresh": {func(r *model.Repo) {
|
||||||
|
r.Issues = []model.Issue{{Number: 1, CreatedAt: t0.Add(-time.Hour), UpdatedAt: t0}}
|
||||||
|
}, map[string]model.Severity{KindIssueFresh: model.Warn}, model.Warn},
|
||||||
"archived repo skips work alerts": {func(r *model.Repo) {
|
"archived repo skips work alerts": {func(r *model.Repo) {
|
||||||
r.Archived = true
|
r.Archived = true
|
||||||
r.PRs = []model.PullRequest{{Number: 1, Fork: true, CreatedAt: t0.Add(-30 * 24 * time.Hour)}}
|
r.PRs = []model.PullRequest{{Number: 1, Fork: true, CreatedAt: t0.Add(-30 * 24 * time.Hour)}}
|
||||||
@@ -125,20 +127,22 @@ func TestEvaluateDisabledThresholds(t *testing.T) {
|
|||||||
r := model.Repo{FullName: "o/r", RefreshedAt: t0, PRs: []model.PullRequest{{Number: 1, Fork: true, CreatedAt: t0.Add(-100 * 24 * time.Hour)}},
|
r := model.Repo{FullName: "o/r", RefreshedAt: t0, PRs: []model.PullRequest{{Number: 1, Fork: true, CreatedAt: t0.Add(-100 * 24 * time.Hour)}},
|
||||||
Issues: []model.Issue{{UpdatedAt: t0.Add(-100 * 24 * time.Hour)}}}
|
Issues: []model.Issue{{UpdatedAt: t0.Add(-100 * 24 * time.Hour)}}}
|
||||||
off := config.Thresholds{PRWarnAfter: -1, PRCritAfter: -1, IssueStaleAfter: -1, WorkflowStuck: -1, DataStaleAfter: -1}
|
off := config.Thresholds{PRWarnAfter: -1, PRCritAfter: -1, IssueStaleAfter: -1, WorkflowStuck: -1, DataStaleAfter: -1}
|
||||||
if a := withoutPROpen(Evaluate(&r, t0, off)); len(a) != 0 {
|
for _, a := range withoutPROpen(Evaluate(&r, t0, off)) {
|
||||||
|
if a.Kind != KindPRFresh && a.Kind != KindIssueFresh {
|
||||||
t.Fatalf("disabled checks produced %+v", a)
|
t.Fatalf("disabled checks produced %+v", a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAgeAdvancesWithoutRefresh(t *testing.T) {
|
func TestAgeAdvancesWithoutRefresh(t *testing.T) {
|
||||||
r := model.Repo{FullName: "o/r", RefreshedAt: t0, PRs: []model.PullRequest{{Number: 1, Fork: true, CreatedAt: t0.Add(-40 * time.Hour)}}}
|
r := model.Repo{FullName: "o/r", RefreshedAt: t0, PRs: []model.PullRequest{{Number: 1, Fork: true, CreatedAt: t0.Add(-40 * time.Hour)}}}
|
||||||
cfg := th()
|
cfg := th()
|
||||||
cfg.DataStaleAfter = -1
|
cfg.DataStaleAfter = -1
|
||||||
if a := withoutPROpen(Evaluate(&r, t0, cfg)); len(a) != 0 {
|
if a := withoutPROpen(Evaluate(&r, t0, cfg)); len(a) != 1 || a[0].Kind != KindPRFresh {
|
||||||
t.Fatalf("unexpected %+v", a)
|
t.Fatalf("a PR below the warn threshold must be fresh: %+v", a)
|
||||||
}
|
}
|
||||||
if a := withoutPROpen(Evaluate(&r, t0.Add(10*time.Hour), cfg)); len(a) != 1 || a[0].Severity != model.Warn {
|
if a := withoutPROpen(Evaluate(&r, t0.Add(10*time.Hour), cfg)); len(a) != 1 || a[0].Kind != KindPRWaiting {
|
||||||
t.Fatalf("PR must cross the warn threshold as time passes: %+v", a)
|
t.Fatalf("PR must turn from fresh to waiting as time passes: %+v", a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,9 +494,6 @@ func TestEvaluatePROpen(t *testing.T) {
|
|||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
r := model.Repo{FullName: "o/r", Up: true, RefreshedAt: t0, Archived: tc.archived, PRs: []model.PullRequest{tc.pr}}
|
r := model.Repo{FullName: "o/r", Up: true, RefreshedAt: t0, Archived: tc.archived, PRs: []model.PullRequest{tc.pr}}
|
||||||
alerts := Evaluate(&r, t0, th())
|
alerts := Evaluate(&r, t0, th())
|
||||||
if r.Health != model.OK {
|
|
||||||
t.Fatalf("health = %v, want ok", r.Health)
|
|
||||||
}
|
|
||||||
if !tc.want {
|
if !tc.want {
|
||||||
if len(alerts) != 0 {
|
if len(alerts) != 0 {
|
||||||
t.Fatalf("alerts = %+v, want none", alerts)
|
t.Fatalf("alerts = %+v, want none", alerts)
|
||||||
@@ -501,21 +502,31 @@ func TestEvaluatePROpen(t *testing.T) {
|
|||||||
}
|
}
|
||||||
want := model.Alert{Severity: model.OK, Repo: "o/r", Kind: KindPROpen, Subject: "#7 fix", Detail: "open for 5h",
|
want := model.Alert{Severity: model.OK, Repo: "o/r", Kind: KindPROpen, Subject: "#7 fix", Detail: "open for 5h",
|
||||||
URL: tc.pr.URL, Ref: "abc123", Author: "alice", Since: tc.pr.CreatedAt}
|
URL: tc.pr.URL, Ref: "abc123", Author: "alice", Since: tc.pr.CreatedAt}
|
||||||
if len(alerts) != 1 || alerts[0] != want {
|
if alerts = onlyPROpen(alerts); len(alerts) != 1 || alerts[0] != want {
|
||||||
t.Fatalf("alerts = %+v, want [%+v]", alerts, want)
|
t.Fatalf("alerts = %+v, want [%+v]", alerts, want)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPROpenDoesNotChangeCounts(t *testing.T) {
|
func onlyPROpen(in []model.Alert) []model.Alert {
|
||||||
|
var out []model.Alert
|
||||||
|
for _, a := range in {
|
||||||
|
if a.Kind == KindPROpen {
|
||||||
|
out = append(out, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPROpenHasNoSeverityOfItsOwn(t *testing.T) {
|
||||||
f := &fakeFetcher{fn: func(name string) (model.Repo, error) {
|
f := &fakeFetcher{fn: func(name string) (model.Repo, error) {
|
||||||
return model.Repo{FullName: name, PRs: []model.PullRequest{{Number: 1, HeadSHA: "s", CreatedAt: t0}}}, nil
|
return model.Repo{FullName: name, PRs: []model.PullRequest{{Number: 1, HeadSHA: "s", CreatedAt: t0}}}, nil
|
||||||
}}
|
}}
|
||||||
c := newCollector(f, "o/a")
|
c := newCollector(f, "o/a")
|
||||||
c.Refresh(context.Background())
|
c.Refresh(context.Background())
|
||||||
v := c.View()
|
v := c.View()
|
||||||
if len(v.Alerts) != 1 || v.Alerts[0].Kind != KindPROpen || v.Crit != 0 || v.Warn != 0 || v.Repos[0].Health != model.OK {
|
if len(onlyPROpen(v.Alerts)) != 1 || v.Alerts[0].Severity != model.Warn || v.Crit != 0 || v.Warn != 1 {
|
||||||
t.Fatalf("view = %+v", v)
|
t.Fatalf("view = %+v", v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -553,3 +564,34 @@ func TestRefreshRepoFailureSkipsRefreshHooks(t *testing.T) {
|
|||||||
case <-time.After(200 * time.Millisecond):
|
case <-time.After(200 * time.Millisecond):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRefreshPublishesEachRepoBeforeTheScanEnds(t *testing.T) {
|
||||||
|
release := make(chan struct{})
|
||||||
|
f := &fakeFetcher{fn: func(name string) (model.Repo, error) {
|
||||||
|
if name == "o/slow" {
|
||||||
|
<-release
|
||||||
|
}
|
||||||
|
return model.Repo{FullName: name, Err: ""}, nil
|
||||||
|
}}
|
||||||
|
cfg := &config.Config{Repos: []string{"o/fast", "o/slow"}, RefreshInterval: time.Hour, Concurrency: 2, Thresholds: th()}
|
||||||
|
c := New(f, cfg, slog.New(slog.NewTextHandler(io.Discard, nil)))
|
||||||
|
c.now = func() time.Time { return t0 }
|
||||||
|
done := make(chan struct{})
|
||||||
|
go func() { c.Refresh(context.Background()); close(done) }()
|
||||||
|
deadline := time.Now().Add(2 * time.Second)
|
||||||
|
for time.Now().Before(deadline) {
|
||||||
|
if v := c.View(); len(v.Repos) == 1 && v.Repos[0].FullName == "o/fast" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(5 * time.Millisecond)
|
||||||
|
}
|
||||||
|
v := c.View()
|
||||||
|
if len(v.Repos) != 1 || v.Repos[0].FullName != "o/fast" || !v.Refreshing || v.Loaded {
|
||||||
|
t.Fatalf("mid-scan view: repos=%d refreshing=%v loaded=%v", len(v.Repos), v.Refreshing, v.Loaded)
|
||||||
|
}
|
||||||
|
close(release)
|
||||||
|
<-done
|
||||||
|
if v := c.View(); len(v.Repos) != 2 || !v.Loaded {
|
||||||
|
t.Fatalf("after scan: repos=%d loaded=%v", len(v.Repos), v.Loaded)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ const (
|
|||||||
KindWorkflowStuck = "workflow_stuck"
|
KindWorkflowStuck = "workflow_stuck"
|
||||||
KindPRWaiting = "pr_waiting"
|
KindPRWaiting = "pr_waiting"
|
||||||
KindPRChecks = "pr_checks_failing"
|
KindPRChecks = "pr_checks_failing"
|
||||||
KindIssuesStale = "issues_stale"
|
KindPRFresh = "pr_fresh"
|
||||||
|
KindIssueStale = "issue_stale"
|
||||||
|
KindIssueFresh = "issue_fresh"
|
||||||
// KindPROpen is informational plumbing for automatic actions; it has OK severity so it never moves health or counts.
|
// KindPROpen is informational plumbing for automatic actions; it has OK severity so it never moves health or counts.
|
||||||
KindPROpen = "pr_open"
|
KindPROpen = "pr_open"
|
||||||
)
|
)
|
||||||
@@ -71,27 +73,20 @@ func Evaluate(r *model.Repo, now time.Time, th config.Thresholds) []model.Alert
|
|||||||
add(model.Crit, KindPRWaiting, subject, "open "+Age(age), pr.URL, pr.CreatedAt)
|
add(model.Crit, KindPRWaiting, subject, "open "+Age(age), pr.URL, pr.CreatedAt)
|
||||||
case th.PRWarnAfter > 0 && age >= th.PRWarnAfter:
|
case th.PRWarnAfter > 0 && age >= th.PRWarnAfter:
|
||||||
add(model.Warn, KindPRWaiting, subject, "open "+Age(age), pr.URL, pr.CreatedAt)
|
add(model.Warn, KindPRWaiting, subject, "open "+Age(age), pr.URL, pr.CreatedAt)
|
||||||
|
default:
|
||||||
|
add(model.Warn, KindPRFresh, subject, "new, open "+Age(age), pr.URL, pr.CreatedAt)
|
||||||
}
|
}
|
||||||
if pr.Checks.State == model.ChecksFail {
|
if pr.Checks.State == model.ChecksFail {
|
||||||
add(model.Warn, KindPRChecks, subject, summarizeChecks(pr.Checks), pr.URL, pr.UpdatedAt)
|
add(model.Warn, KindPRChecks, subject, summarizeChecks(pr.Checks), pr.URL, pr.UpdatedAt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if th.IssueStaleAfter > 0 {
|
|
||||||
var stale int
|
|
||||||
var oldest time.Time
|
|
||||||
for _, is := range r.Issues {
|
for _, is := range r.Issues {
|
||||||
if now.Sub(is.UpdatedAt) >= th.IssueStaleAfter {
|
subject := fmt.Sprintf("#%d %s", is.Number, is.Title)
|
||||||
stale++
|
if idle := now.Sub(is.UpdatedAt); th.IssueStaleAfter > 0 && idle >= th.IssueStaleAfter {
|
||||||
if oldest.IsZero() || is.UpdatedAt.Before(oldest) {
|
add(model.Warn, KindIssueStale, subject, "no activity for "+Age(idle), is.URL, is.UpdatedAt)
|
||||||
oldest = is.UpdatedAt
|
} else {
|
||||||
}
|
add(model.Warn, KindIssueFresh, subject, "new, open "+Age(now.Sub(is.CreatedAt)), is.URL, is.CreatedAt)
|
||||||
}
|
|
||||||
}
|
|
||||||
if stale > 0 {
|
|
||||||
add(model.Warn, KindIssuesStale, fmt.Sprintf("%d stale issues", stale),
|
|
||||||
"no activity for "+Age(th.IssueStaleAfter)+" or more",
|
|
||||||
r.URL+"/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-asc", oldest)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return alerts
|
return alerts
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import (
|
|||||||
const (
|
const (
|
||||||
maxFailingNames = 5
|
maxFailingNames = 5
|
||||||
runsPerWorkflow = 5
|
runsPerWorkflow = 5
|
||||||
|
// freshRunsWindowDays bounds the created filter of the confirming run query.
|
||||||
|
freshRunsWindowDays = 30
|
||||||
maxWorkflows = 100
|
maxWorkflows = 100
|
||||||
eventPullRequest = "pull_request"
|
eventPullRequest = "pull_request"
|
||||||
eventPullReqTgt = "pull_request_target"
|
eventPullReqTgt = "pull_request_target"
|
||||||
@@ -374,9 +376,11 @@ func (c *Client) workflowRuns(ctx context.Context, full string, id int64, branch
|
|||||||
path := fmt.Sprintf("/repos/%s/actions/workflows/%d/runs", full, id)
|
path := fmt.Sprintf("/repos/%s/actions/workflows/%d/runs", full, id)
|
||||||
get := c.getJSON
|
get := c.getJSON
|
||||||
if fresh {
|
if fresh {
|
||||||
// GitHub can keep answering one exact query from an old cached result, for weeks, whatever
|
// GitHub can keep answering a branch query from an old cached result, for weeks, whatever
|
||||||
// the connection. A different query string skips that entry and reads current runs.
|
// the connection, and page=1 alone does not skip it. A created filter changes the query
|
||||||
|
// every day and reads current runs.
|
||||||
q.Set("page", "1")
|
q.Set("page", "1")
|
||||||
|
q.Set("created", ">="+c.now().UTC().AddDate(0, 0, -freshRunsWindowDays).Format(time.DateOnly))
|
||||||
get = c.getJSONFresh
|
get = c.getJSONFresh
|
||||||
}
|
}
|
||||||
if err := get(ctx, full, path, q, &out); err != nil {
|
if err := get(ctx, full, path, q, &out); err != nil {
|
||||||
|
|||||||
@@ -461,12 +461,12 @@ func TestAPIErrorMessageParsing(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// staleThenFresh models GitHub answering one exact query from an old cached result: the plain
|
// staleThenFresh models GitHub answering one exact query from an old cached result: the plain
|
||||||
// query returns an old failing run every time, and the same query with page=1 returns current runs.
|
// query returns an old failing run every time, and the same query with a created filter returns current runs.
|
||||||
func staleThenFresh(f *fakeGitHub, path string) *atomic.Int64 {
|
func staleThenFresh(f *fakeGitHub, path string) *atomic.Int64 {
|
||||||
var calls atomic.Int64
|
var calls atomic.Int64
|
||||||
f.routes[path] = func(w http.ResponseWriter, r *http.Request) {
|
f.routes[path] = func(w http.ResponseWriter, r *http.Request) {
|
||||||
calls.Add(1)
|
calls.Add(1)
|
||||||
if r.URL.Query().Get("page") == "" {
|
if r.URL.Query().Get("created") == "" {
|
||||||
_, _ = w.Write([]byte(`{"workflow_runs":[
|
_, _ = w.Write([]byte(`{"workflow_runs":[
|
||||||
{"id":1,"html_url":"old","event":"schedule","head_branch":"main","status":"completed","conclusion":"failure","created_at":"2026-09-11T03:02:00Z"}]}`))
|
{"id":1,"html_url":"old","event":"schedule","head_branch":"main","status":"completed","conclusion":"failure","created_at":"2026-09-11T03:02:00Z"}]}`))
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -158,7 +158,8 @@ func (a *Actions) statusRows(ctx context.Context, rt *actionRuntime) (map[alertR
|
|||||||
if !rt.fetched.IsZero() && a.now().Sub(rt.fetched) < statusCacheTTL {
|
if !rt.fetched.IsZero() && a.now().Sub(rt.fetched) < statusCacheTTL {
|
||||||
return rt.rows, rt.err
|
return rt.rows, rt.err
|
||||||
}
|
}
|
||||||
rows, err := a.fetchStatus(ctx, rt.cfg)
|
// A client that disconnects mid-request must not fail the fetch that every later request reuses.
|
||||||
|
rows, err := a.fetchStatus(context.WithoutCancel(ctx), rt.cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.log.Warn("action status unavailable", "action", rt.cfg.ID, "err", err)
|
a.log.Warn("action status unavailable", "action", rt.cfg.ID, "err", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package web
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
@@ -407,3 +408,15 @@ func TestRedirectDoesNotForwardToken(t *testing.T) {
|
|||||||
t.Fatal("bearer token forwarded across a redirect")
|
t.Fatal("bearer token forwarded across a redirect")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStatusFetchSurvivesCancelledRequest(t *testing.T) {
|
||||||
|
fh := newFakeHook(t)
|
||||||
|
fh.statBody = `[{"repo":"o/r","url":"` + alertURL + `","state":"running"}]`
|
||||||
|
h := newActionServer(t, nil, fh.srv.URL)
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
cancel()
|
||||||
|
rows, err := h.actions.statusRows(ctx, h.actions.list[0])
|
||||||
|
if err != nil || len(rows) != 1 {
|
||||||
|
t.Fatalf("rows=%d err=%v, want the fetch to complete despite the cancelled request", len(rows), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -138,10 +138,10 @@ func TestNewAutoRunnerNilWithoutAutoActions(t *testing.T) {
|
|||||||
|
|
||||||
func TestStateCarriesPROpenRef(t *testing.T) {
|
func TestStateCarriesPROpenRef(t *testing.T) {
|
||||||
st := buildState(autoView(autoPR(1, "abc", "x", nil)), true)
|
st := buildState(autoView(autoPR(1, "abc", "x", nil)), true)
|
||||||
if len(st.Alerts) != 1 || st.Alerts[0].Kind != collector.KindPROpen || st.Alerts[0].Ref != "abc" || st.Alerts[0].Severity != "ok" {
|
if len(st.Alerts) != 2 || st.Alerts[0].Kind != collector.KindPROpen || st.Alerts[0].Ref != "abc" || st.Alerts[0].Severity != "ok" || st.Alerts[1].Kind != collector.KindPRFresh {
|
||||||
t.Fatalf("alerts = %+v", st.Alerts)
|
t.Fatalf("alerts = %+v", st.Alerts)
|
||||||
}
|
}
|
||||||
if st.Counts.Crit != 0 || st.Counts.Warn != 0 || st.Repos[0].Health != "ok" {
|
if st.Repos[0].Health != "warn" {
|
||||||
t.Fatalf("counts/health changed: %+v %s", st.Counts, st.Repos[0].Health)
|
t.Fatalf("health = %s, want warn", st.Repos[0].Health)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -37,11 +37,11 @@
|
|||||||
"happy-dom": "^20.14.5",
|
"happy-dom": "^20.14.5",
|
||||||
"prettier": "^3.9.9",
|
"prettier": "^3.9.9",
|
||||||
"tailwindcss": "^4.3.3",
|
"tailwindcss": "^4.3.3",
|
||||||
"typescript": "~5.9.3",
|
"typescript": "~6.0.3",
|
||||||
"typescript-eslint": "^8.70.1",
|
"typescript-eslint": "^8.70.1",
|
||||||
"vite": "^8.3.1",
|
"vite": "^8.3.1",
|
||||||
"vitest": "^5.0.1",
|
"vitest": "^5.0.1",
|
||||||
"vue-tsc": "^3.3.11"
|
"vue-tsc": "^3.3.11"
|
||||||
},
|
},
|
||||||
"packageManager": "[email protected].3"
|
"packageManager": "[email protected].5"
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+169
-178
@@ -22,13 +22,13 @@ importers:
|
|||||||
version: 7.3.1
|
version: 7.3.1
|
||||||
'@fortawesome/vue-fontawesome':
|
'@fortawesome/vue-fontawesome':
|
||||||
specifier: ^3.3.3
|
specifier: ^3.3.3
|
||||||
version: 3.3.3(@fortawesome/[email protected])([email protected](typescript@5.9.3))
|
version: 3.3.3(@fortawesome/[email protected])([email protected](typescript@6.0.3))
|
||||||
'@lucide/vue':
|
'@lucide/vue':
|
||||||
specifier: ^1.49.0
|
specifier: ^1.49.0
|
||||||
version: 1.50.0([email protected](typescript@5.9.3))
|
version: 1.53.0([email protected](typescript@6.0.3))
|
||||||
'@vueuse/core':
|
'@vueuse/core':
|
||||||
specifier: ^15.0.0
|
specifier: ^15.0.0
|
||||||
version: 15.0.0([email protected](typescript@5.9.3))
|
version: 15.0.0([email protected](typescript@6.0.3))
|
||||||
class-variance-authority:
|
class-variance-authority:
|
||||||
specifier: ^0.7.1
|
specifier: ^0.7.1
|
||||||
version: 0.7.1
|
version: 0.7.1
|
||||||
@@ -37,44 +37,44 @@ importers:
|
|||||||
version: 2.1.1
|
version: 2.1.1
|
||||||
pinia:
|
pinia:
|
||||||
specifier: ^4.0.3
|
specifier: ^4.0.3
|
||||||
version: 4.0.3(@vue/[email protected])(typescript@5.9.3)([email protected](typescript@5.9.3))
|
version: 4.0.3(@vue/[email protected])(typescript@6.0.3)([email protected](typescript@6.0.3))
|
||||||
reka-ui:
|
reka-ui:
|
||||||
specifier: ^2.10.5
|
specifier: ^2.10.5
|
||||||
version: 2.10.5([email protected](typescript@5.9.3))
|
version: 2.11.0([email protected](typescript@6.0.3))
|
||||||
tailwind-merge:
|
tailwind-merge:
|
||||||
specifier: ^3.7.0
|
specifier: ^3.7.0
|
||||||
version: 3.7.0
|
version: 3.7.0
|
||||||
vue:
|
vue:
|
||||||
specifier: ^3.5.43
|
specifier: ^3.5.43
|
||||||
version: 3.5.43(typescript@5.9.3)
|
version: 3.5.43(typescript@6.0.3)
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@eslint/js':
|
'@eslint/js':
|
||||||
specifier: ^10.0.1
|
specifier: ^10.0.1
|
||||||
version: 10.0.1([email protected]([email protected]))
|
version: 10.0.1([email protected]([email protected]))
|
||||||
'@tailwindcss/vite':
|
'@tailwindcss/vite':
|
||||||
specifier: ^4.3.3
|
specifier: ^4.3.3
|
||||||
version: 4.3.3([email protected].2(@types/[email protected])([email protected]))
|
version: 4.3.3([email protected].4(@types/[email protected])([email protected]))
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^26.6.2
|
specifier: ^26.6.2
|
||||||
version: 26.6.4
|
version: 26.6.4
|
||||||
'@vitejs/plugin-vue':
|
'@vitejs/plugin-vue':
|
||||||
specifier: ^6.0.9
|
specifier: ^6.0.9
|
||||||
version: 6.0.9([email protected].2(@types/[email protected])([email protected]))([email protected](typescript@5.9.3))
|
version: 6.0.9([email protected].4(@types/[email protected])([email protected]))([email protected](typescript@6.0.3))
|
||||||
'@vue/test-utils':
|
'@vue/test-utils':
|
||||||
specifier: ^2.5.1
|
specifier: ^2.5.1
|
||||||
version: 2.5.1(@vue/[email protected])(@vue/[email protected])([email protected](typescript@5.9.3))
|
version: 2.5.1(@vue/[email protected])(@vue/[email protected])([email protected](typescript@6.0.3))
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^10.11.0
|
specifier: ^10.11.0
|
||||||
version: 10.12.0([email protected])
|
version: 10.12.0([email protected])
|
||||||
eslint-plugin-vue:
|
eslint-plugin-vue:
|
||||||
specifier: ^10.11.1
|
specifier: ^10.11.1
|
||||||
version: 10.11.1(@typescript-eslint/[email protected].0([email protected]([email protected]))(typescript@5.9.3))([email protected]([email protected]))([email protected]([email protected]([email protected])))
|
version: 10.11.1(@typescript-eslint/[email protected].1([email protected]([email protected]))(typescript@6.0.3))([email protected]([email protected]))([email protected]([email protected]([email protected])))
|
||||||
globals:
|
globals:
|
||||||
specifier: ^17.12.0
|
specifier: ^17.12.0
|
||||||
version: 17.13.0
|
version: 17.13.0
|
||||||
happy-dom:
|
happy-dom:
|
||||||
specifier: ^20.14.5
|
specifier: ^20.14.5
|
||||||
version: 20.14.5
|
version: 20.14.6
|
||||||
prettier:
|
prettier:
|
||||||
specifier: ^3.9.9
|
specifier: ^3.9.9
|
||||||
version: 3.9.9
|
version: 3.9.9
|
||||||
@@ -82,20 +82,20 @@ importers:
|
|||||||
specifier: ^4.3.3
|
specifier: ^4.3.3
|
||||||
version: 4.3.3
|
version: 4.3.3
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ~5.9.3
|
specifier: ~6.0.3
|
||||||
version: 5.9.3
|
version: 6.0.3
|
||||||
typescript-eslint:
|
typescript-eslint:
|
||||||
specifier: ^8.70.1
|
specifier: ^8.70.1
|
||||||
version: 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
version: 8.71.1([email protected]([email protected]))(typescript@6.0.3)
|
||||||
vite:
|
vite:
|
||||||
specifier: ^8.3.1
|
specifier: ^8.3.1
|
||||||
version: 8.3.2(@types/[email protected])([email protected])
|
version: 8.3.4(@types/[email protected])([email protected])
|
||||||
vitest:
|
vitest:
|
||||||
specifier: ^5.0.1
|
specifier: ^5.0.1
|
||||||
version: 5.0.3(@types/[email protected])([email protected].5)([email protected].2(@types/[email protected])([email protected]))
|
version: 5.0.3(@types/[email protected])([email protected].6)([email protected].4(@types/[email protected])([email protected]))
|
||||||
vue-tsc:
|
vue-tsc:
|
||||||
specifier: ^3.3.11
|
specifier: ^3.3.11
|
||||||
version: 3.3.12(typescript@5.9.3)
|
version: 3.3.12(typescript@6.0.3)
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
@@ -170,8 +170,10 @@ packages:
|
|||||||
'@floating-ui/[email protected]':
|
'@floating-ui/[email protected]':
|
||||||
resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==}
|
resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==}
|
||||||
|
|
||||||
'@floating-ui/vue@1.1.11':
|
'@floating-ui/vue@2.0.1':
|
||||||
resolution: {integrity: sha512-HzHKCNVxnGS35r9fCHBc3+uCnjw9IWIlCPL683cGgM9Kgj2BiAl8x1mS7vtvP6F9S/e/q4O6MApwSHj8hNLGfw==}
|
resolution: {integrity: sha512-043dyEKD9TDSfz080YH2vobubgg+NIo/9Fw4RAl7sEMpD8Am1DNrrSTl/GpMBjyGHoD/FbJY2QLawY+HSQsEIA==}
|
||||||
|
peerDependencies:
|
||||||
|
vue: '>=3.3.0'
|
||||||
|
|
||||||
'@fontsource-variable/[email protected]':
|
'@fontsource-variable/[email protected]':
|
||||||
resolution: {integrity: sha512-F32xpS2NsGYoQi2ADSkKTgpJj7ozajsGgDJ8woTnqjmIB+dxDIqImjl4pXZVEExu8UFZ2ndhmX18EBS/hdz3Lw==}
|
resolution: {integrity: sha512-F32xpS2NsGYoQi2ADSkKTgpJj7ozajsGgDJ8woTnqjmIB+dxDIqImjl4pXZVEExu8UFZ2ndhmX18EBS/hdz3Lw==}
|
||||||
@@ -248,8 +250,8 @@ packages:
|
|||||||
'@keyv/[email protected]':
|
'@keyv/[email protected]':
|
||||||
resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==}
|
resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==}
|
||||||
|
|
||||||
'@lucide/[email protected]0.0':
|
'@lucide/[email protected]3.0':
|
||||||
resolution: {integrity: sha512-/cYAYqHIMUcVbhGYPk+GqgPqlqTKCFfyGrpXvH/6z5v7sWRoWBHViYwO3cNgmupZCBY+4WB016wN6CkXNcy0Yw==}
|
resolution: {integrity: sha512-WtBYxiwNVd9yP/UKeMbxAntZqrd50pWxhkXrxxOcYJc4XhsO0pkKbUed+sEh08C1u07zj5I3Rz6AU1v9wHEDqA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vue: '>=3.0.1'
|
vue: '>=3.0.1'
|
||||||
|
|
||||||
@@ -490,63 +492,63 @@ packages:
|
|||||||
'@types/[email protected]':
|
'@types/[email protected]':
|
||||||
resolution: {integrity: sha512-67MQl+fpWKVTT1NYdnmo3U4sc/xPo/zQBncVnI74qmQa0z/b+1g6iYqNmGCPbxO+zz2aklb08a0oHfegiVd0/w==}
|
resolution: {integrity: sha512-67MQl+fpWKVTT1NYdnmo3U4sc/xPo/zQBncVnI74qmQa0z/b+1g6iYqNmGCPbxO+zz2aklb08a0oHfegiVd0/w==}
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0':
|
'@typescript-eslint/[email protected].1':
|
||||||
resolution: {integrity: sha512-pqcS9c1HxZTHt7End4nXqd0s5lJrrFzrgCkKFJrsbUnaL6M3+6oBFZaslg6Gjsl3argl2DDRFROnXARaZ2e4Nw==}
|
resolution: {integrity: sha512-nNlBf6HuotqMgZvSkWD5hNdemiBIxQ2NmrlgfcUIeZRs+BbakjscCQRq/Hb74EFVnFiSWWdL12JruqwBy3ERDw==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@typescript-eslint/parser': ^8.71.0
|
'@typescript-eslint/parser': ^8.71.1
|
||||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||||
typescript: '>=4.8.4 <6.1.0'
|
typescript: '>=4.8.4 <6.1.0'
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0':
|
'@typescript-eslint/[email protected].1':
|
||||||
resolution: {integrity: sha512-CG4nPk1f2zc8yw4pALqHsFYH2hdo+h1T9daSp21+Hnxi9LOE3GT9hAfTKJCBXVNM2GmYs1eMEP615wPoeOgk3A==}
|
resolution: {integrity: sha512-oM/5sAqz/l1v/zYK1qTOPrn2+JIrBGC1V6uNYucRO5gh6eT9vWJ/RhPbGE59byvZEUQ4VP6XkLBaS5Jti5jpvw==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||||
typescript: '>=4.8.4 <6.1.0'
|
typescript: '>=4.8.4 <6.1.0'
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0':
|
'@typescript-eslint/[email protected].1':
|
||||||
resolution: {integrity: sha512-aABjw5rjBacYONVPaPiWOCjJu0vEF4a25iQuodlmQYL1trtLZ0X/y+2Vzl3BKI1odM4LnwLE1oUDXYp1wzx1TQ==}
|
resolution: {integrity: sha512-Oijc9RUsohHjncg6iGi7gCtjnEjYt9FWv9u6ygK8uKcHK5eLjLAkqERQ9BaytbpceOFdk6kifPCS/zAZE+A99g==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.8.4 <6.1.0'
|
typescript: '>=4.8.4 <6.1.0'
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0':
|
'@typescript-eslint/[email protected].1':
|
||||||
resolution: {integrity: sha512-gWF0BhUcnjZxSpLE8ngS/59n2SB0J3YqRxvX1+2aoRJk9hNtHSLOV+TcarFiOr5ipXm3yc1QrI4c9YZc8zyCxw==}
|
resolution: {integrity: sha512-1YUDZXdTnXLlob03SFHBipdyMBsDVm7zoSz0ytTJ39dk5J1TgsTK03VlR/dLXG/RLLUrPcYbD4rp23BmHxHP0w==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0':
|
'@typescript-eslint/[email protected].1':
|
||||||
resolution: {integrity: sha512-Z1UlWHADEK2Mlb9NpWfDeSjqoZ5EyrOv4R3eQpbkzqn/EwaIdOpXXupEA1+0ZIOSJSZZDBHG0BrQyN8zUG6Pwg==}
|
resolution: {integrity: sha512-oTvkml5SxXhgg+WWKhod5qWQICDXtOB+/Hi9VdPKFAANJ2b7YOgMffgvzXuqog7R6A/JtrzRf128dsxummyWhg==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.8.4 <6.1.0'
|
typescript: '>=4.8.4 <6.1.0'
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0':
|
'@typescript-eslint/[email protected].1':
|
||||||
resolution: {integrity: sha512-i8uO1qbdxeKgRnS5sCRt6On3/nfo2d2DwQe3Yvjx543zLy7r8ySqRuPPiIIXAhS03U0v5NfAFx+rUgxFzKKwNw==}
|
resolution: {integrity: sha512-kH3t3jZCYv2PZSBEWPKTariLrCaoF1CLoPitYFBJOhAGEwWnSRAtGEifrfrpBa4K9JlwWNZotgA5w3/wLSk/FQ==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||||
typescript: '>=4.8.4 <6.1.0'
|
typescript: '>=4.8.4 <6.1.0'
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0':
|
'@typescript-eslint/[email protected].1':
|
||||||
resolution: {integrity: sha512-cJ4OoxPGWvFnBTnSZyaU+qJzGTqPTGJY+gDchj6cRyLRdmIdt4rcsE4twj+zPfrNiWuVi38wijHzShL++Z9atQ==}
|
resolution: {integrity: sha512-ybYnPTUwg3VQQOFEiBPLs8Jxl1ry2vXdn1kVKguomBbvxpetdu3MKTNDqFNUrlG8ylP9MpZosmXMFYlGQHk1oQ==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0':
|
'@typescript-eslint/[email protected].1':
|
||||||
resolution: {integrity: sha512-PEEF4G5sLLWAS5BpPrUvms4ySZkiBQQZM4z+3ReI46axK5Vqr/vXBQatJQIZZOYdGyPUAKTtsrWzpqKuU+3DEw==}
|
resolution: {integrity: sha512-pSKSEK1JJpHs6KiKVtABCE4iJK5d7FLFzDXQNBQ2oRY7LEd3UwOt3TZemTgu9syTIf56dJWlTn/pdmrO9oKUXQ==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.8.4 <6.1.0'
|
typescript: '>=4.8.4 <6.1.0'
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0':
|
'@typescript-eslint/[email protected].1':
|
||||||
resolution: {integrity: sha512-pKR/tEMVrXZG23UFKUn5BQf3zfmfk7KQceI2cGzywZ5nxM5Eu3hEJU1utjWzydtzBbcJAQhHN8iPCxobHpPcZQ==}
|
resolution: {integrity: sha512-CBjT6gfAz3DW2j9Q4moFnqt208Aq+506sVGXfpRcyAeqn0EpayL0mjdWoCO2t3RC7GewNrFxdeehuEaPg6DMzQ==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||||
typescript: '>=4.8.4 <6.1.0'
|
typescript: '>=4.8.4 <6.1.0'
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0':
|
'@typescript-eslint/[email protected].1':
|
||||||
resolution: {integrity: sha512-8eQ9R218XORK+KLosnf4bu/QsUXvUyVwTbArg7/0NMB1Pu87OJKvj4nhFblkYE8gQV73mW1dx1ptlPCkwRGa7A==}
|
resolution: {integrity: sha512-0GxiUGqMU0qXJt58cBsiG3DP8lUmBaFo2vChtUX+CT7PnR3v/VGLLrzVP4K9r1lNiZXjHYefMBbPunplr09v6w==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
|
|
||||||
'@vitejs/[email protected]':
|
'@vitejs/[email protected]':
|
||||||
@@ -897,8 +899,8 @@ packages:
|
|||||||
[email protected]:
|
[email protected]:
|
||||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||||
|
|
||||||
[email protected].5:
|
[email protected].6:
|
||||||
resolution: {integrity: sha512-x/RzkpWO40bTjIoT30iQtt64FLLmH/iRcUCN2X//bLx7H3ifkdfPXyqsro/OYtqzIAhiLMMA7mmiOR9C3NOKjQ==}
|
resolution: {integrity: sha512-5DDsf4QmEIlRL6NkCv/fxSjYHHkZceL/IaYQdJc2h3G7DRTEai++VTjbfL0LB9geW2VrA3+vrjF3Efx+OTtX0Q==}
|
||||||
engines: {node: '>=20.0.0'}
|
engines: {node: '>=20.0.0'}
|
||||||
|
|
||||||
[email protected]:
|
[email protected]:
|
||||||
@@ -1222,6 +1224,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==}
|
resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==}
|
||||||
engines: {node: ^10 || ^12 || >=14}
|
engines: {node: ^10 || ^12 || >=14}
|
||||||
|
|
||||||
|
[email protected]:
|
||||||
|
resolution: {integrity: sha512-49cGhUbXj8Qenv0iTMxA1cFBzxXoctpC9Ujd77t1WcbJIr6nF/eI7g/8MgxrYldFRuAXvja7xQRwavoW7kgrxQ==}
|
||||||
|
engines: {node: ^10 || ^12 || >=14}
|
||||||
|
|
||||||
[email protected]:
|
[email protected]:
|
||||||
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
@@ -1242,8 +1248,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==}
|
resolution: {integrity: sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==}
|
||||||
engines: {node: '>=20'}
|
engines: {node: '>=20'}
|
||||||
|
|
||||||
[email protected]0.5:
|
[email protected]1.0:
|
||||||
resolution: {integrity: sha512-/8o0y9BThE0hcHKFg+3770tWcJh3qKdOEFxLOPb9HIajXeFoH/J530cZH62jUJunbqwBgpSBL9v7nB8LJ5pDXA==}
|
resolution: {integrity: sha512-ilkpm4bIAol4jwzm4tpm3WVcffyGOpqksNZL1k1qO9QmIwAA+q8jroxjkUGLEn/GddfdExFfvofWfQiKZszUeQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vue: '>= 3.4.0'
|
vue: '>= 3.4.0'
|
||||||
|
|
||||||
@@ -1307,15 +1313,15 @@ packages:
|
|||||||
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
|
||||||
[email protected].0:
|
[email protected].1:
|
||||||
resolution: {integrity: sha512-fBdHYiqQ14RW6mOMXD14Svn82ZsCYAoQSzGRzyEjR59S5A2Krh/l7fGTOQ7iCr8gGy/mHVXtEF7s5fgjEdV0Pw==}
|
resolution: {integrity: sha512-oiNVPC3/NbV1FpaHU07l8O6ynqG9v4PAiW2WvTrAmZdR0f2HI/gE668ElMLCK7Xbsu5k2fK5C4fXNiq05j7/nQ==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
|
||||||
typescript: '>=4.8.4 <6.1.0'
|
typescript: '>=4.8.4 <6.1.0'
|
||||||
|
|
||||||
typescript@5.9.3:
|
typescript@6.0.3:
|
||||||
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
|
resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==}
|
||||||
engines: {node: '>=14.17'}
|
engines: {node: '>=14.17'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
@@ -1328,8 +1334,8 @@ packages:
|
|||||||
[email protected]:
|
[email protected]:
|
||||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||||
|
|
||||||
[email protected].2:
|
[email protected].4:
|
||||||
resolution: {integrity: sha512-SQr1x6W5vVSbROg7vsyXIaxK9b0G7zsT68acdWWRmnBUsgDieLCRG+Rep9WdZgcposvv/GSnr4GUUBqB3vXq6w==}
|
resolution: {integrity: sha512-IftLE8phJhdNRIGNEV4JCCvfNScoZQVfcXaN8TQropWGJtOHcu+iAB9pHcuGvmEb/kddw0LBe/jS8ztdC6xdiQ==}
|
||||||
engines: {node: ^20.19.0 || >=22.12.0}
|
engines: {node: ^20.19.0 || >=22.12.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -1418,17 +1424,6 @@ packages:
|
|||||||
[email protected]:
|
[email protected]:
|
||||||
resolution: {integrity: sha512-LwcxzeliO9fkQcpJG0PoX8X5kmAhKmH9wkpDLxNabwzkQ9Zeib2YVHwFV4pcWmMLfXVfjr/dSV+DaJ3cIPgSNA==}
|
resolution: {integrity: sha512-LwcxzeliO9fkQcpJG0PoX8X5kmAhKmH9wkpDLxNabwzkQ9Zeib2YVHwFV4pcWmMLfXVfjr/dSV+DaJ3cIPgSNA==}
|
||||||
|
|
||||||
[email protected]:
|
|
||||||
resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
hasBin: true
|
|
||||||
peerDependencies:
|
|
||||||
'@vue/composition-api': ^1.0.0-rc.1
|
|
||||||
vue: ^3.0.0-0 || ^2.6.0
|
|
||||||
peerDependenciesMeta:
|
|
||||||
'@vue/composition-api':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
[email protected]:
|
[email protected]:
|
||||||
resolution: {integrity: sha512-Gk6gRDj0n/fkRa3C3l0bBheoBckUq/Rs0F/TvMWIS6nzzx67amAViMe9CkNgsP2tXyQONvGiHQESHwFtZ3aYDA==}
|
resolution: {integrity: sha512-Gk6gRDj0n/fkRa3C3l0bBheoBckUq/Rs0F/TvMWIS6nzzx67amAViMe9CkNgsP2tXyQONvGiHQESHwFtZ3aYDA==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
@@ -1559,14 +1554,11 @@ snapshots:
|
|||||||
|
|
||||||
'@floating-ui/[email protected]': {}
|
'@floating-ui/[email protected]': {}
|
||||||
|
|
||||||
'@floating-ui/vue@1.1.11([email protected](typescript@5.9.3))':
|
'@floating-ui/vue@2.0.1([email protected](typescript@6.0.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@floating-ui/dom': 1.8.0
|
'@floating-ui/dom': 1.8.0
|
||||||
'@floating-ui/utils': 0.2.12
|
'@floating-ui/utils': 0.2.12
|
||||||
vue-demi: 0.14.10([email protected](typescript@5.9.3))
|
vue: 3.5.43(typescript@6.0.3)
|
||||||
transitivePeerDependencies:
|
|
||||||
- '@vue/composition-api'
|
|
||||||
- vue
|
|
||||||
|
|
||||||
'@fontsource-variable/[email protected]': {}
|
'@fontsource-variable/[email protected]': {}
|
||||||
|
|
||||||
@@ -1582,10 +1574,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@fortawesome/fontawesome-common-types': 7.3.1
|
'@fortawesome/fontawesome-common-types': 7.3.1
|
||||||
|
|
||||||
'@fortawesome/[email protected](@fortawesome/[email protected])([email protected](typescript@5.9.3))':
|
'@fortawesome/[email protected](@fortawesome/[email protected])([email protected](typescript@6.0.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@fortawesome/fontawesome-svg-core': 7.3.1
|
'@fortawesome/fontawesome-svg-core': 7.3.1
|
||||||
vue: 3.5.43(typescript@5.9.3)
|
vue: 3.5.43(typescript@6.0.3)
|
||||||
|
|
||||||
'@humanfs/[email protected]':
|
'@humanfs/[email protected]':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1638,9 +1630,9 @@ snapshots:
|
|||||||
|
|
||||||
'@keyv/[email protected]': {}
|
'@keyv/[email protected]': {}
|
||||||
|
|
||||||
'@lucide/[email protected]0.0([email protected](typescript@5.9.3))':
|
'@lucide/[email protected]3.0([email protected](typescript@6.0.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
vue: 3.5.43(typescript@5.9.3)
|
vue: 3.5.43(typescript@6.0.3)
|
||||||
|
|
||||||
'@one-ini/[email protected]': {}
|
'@one-ini/[email protected]': {}
|
||||||
|
|
||||||
@@ -1758,19 +1750,19 @@ snapshots:
|
|||||||
'@tailwindcss/oxide-win32-arm64-msvc': 4.3.3
|
'@tailwindcss/oxide-win32-arm64-msvc': 4.3.3
|
||||||
'@tailwindcss/oxide-win32-x64-msvc': 4.3.3
|
'@tailwindcss/oxide-win32-x64-msvc': 4.3.3
|
||||||
|
|
||||||
'@tailwindcss/[email protected]([email protected].2(@types/[email protected])([email protected]))':
|
'@tailwindcss/[email protected]([email protected].4(@types/[email protected])([email protected]))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tailwindcss/node': 4.3.3
|
'@tailwindcss/node': 4.3.3
|
||||||
'@tailwindcss/oxide': 4.3.3
|
'@tailwindcss/oxide': 4.3.3
|
||||||
tailwindcss: 4.3.3
|
tailwindcss: 4.3.3
|
||||||
vite: 8.3.2(@types/[email protected])([email protected])
|
vite: 8.3.4(@types/[email protected])([email protected])
|
||||||
|
|
||||||
'@tanstack/[email protected]': {}
|
'@tanstack/[email protected]': {}
|
||||||
|
|
||||||
'@tanstack/[email protected]([email protected](typescript@5.9.3))':
|
'@tanstack/[email protected]([email protected](typescript@6.0.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tanstack/virtual-core': 3.17.11
|
'@tanstack/virtual-core': 3.17.11
|
||||||
vue: 3.5.43(typescript@5.9.3)
|
vue: 3.5.43(typescript@6.0.3)
|
||||||
|
|
||||||
'@types/[email protected]':
|
'@types/[email protected]':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1797,111 +1789,111 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 26.6.4
|
'@types/node': 26.6.4
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0(@typescript-eslint/[email protected].0([email protected]([email protected]))(typescript@5.9.3))([email protected]([email protected]))(typescript@5.9.3)':
|
'@typescript-eslint/[email protected].1(@typescript-eslint/[email protected].1([email protected]([email protected]))(typescript@6.0.3))([email protected]([email protected]))(typescript@6.0.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/regexpp': 4.12.2
|
'@eslint-community/regexpp': 4.12.2
|
||||||
'@typescript-eslint/parser': 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
'@typescript-eslint/parser': 8.71.1([email protected]([email protected]))(typescript@6.0.3)
|
||||||
'@typescript-eslint/scope-manager': 8.71.0
|
'@typescript-eslint/scope-manager': 8.71.1
|
||||||
'@typescript-eslint/type-utils': 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
'@typescript-eslint/type-utils': 8.71.1([email protected]([email protected]))(typescript@6.0.3)
|
||||||
'@typescript-eslint/utils': 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
'@typescript-eslint/utils': 8.71.1([email protected]([email protected]))(typescript@6.0.3)
|
||||||
'@typescript-eslint/visitor-keys': 8.71.0
|
'@typescript-eslint/visitor-keys': 8.71.1
|
||||||
eslint: 10.12.0([email protected])
|
eslint: 10.12.0([email protected])
|
||||||
ignore: 7.0.11
|
ignore: 7.0.11
|
||||||
natural-compare: 1.4.0
|
natural-compare: 1.4.0
|
||||||
ts-api-utils: 2.5.0(typescript@5.9.3)
|
ts-api-utils: 2.5.0(typescript@6.0.3)
|
||||||
typescript: 5.9.3
|
typescript: 6.0.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0([email protected]([email protected]))(typescript@5.9.3)':
|
'@typescript-eslint/[email protected].1([email protected]([email protected]))(typescript@6.0.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/scope-manager': 8.71.0
|
'@typescript-eslint/scope-manager': 8.71.1
|
||||||
'@typescript-eslint/types': 8.71.0
|
'@typescript-eslint/types': 8.71.1
|
||||||
'@typescript-eslint/typescript-estree': 8.71.0(typescript@5.9.3)
|
'@typescript-eslint/typescript-estree': 8.71.1(typescript@6.0.3)
|
||||||
'@typescript-eslint/visitor-keys': 8.71.0
|
'@typescript-eslint/visitor-keys': 8.71.1
|
||||||
debug: 4.4.3
|
debug: 4.4.3
|
||||||
eslint: 10.12.0([email protected])
|
eslint: 10.12.0([email protected])
|
||||||
typescript: 5.9.3
|
typescript: 6.0.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0(typescript@5.9.3)':
|
'@typescript-eslint/[email protected].1(typescript@6.0.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/tsconfig-utils': 8.71.0(typescript@5.9.3)
|
'@typescript-eslint/tsconfig-utils': 8.71.1(typescript@6.0.3)
|
||||||
'@typescript-eslint/types': 8.71.0
|
'@typescript-eslint/types': 8.71.1
|
||||||
debug: 4.4.3
|
debug: 4.4.3
|
||||||
typescript: 5.9.3
|
typescript: 6.0.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0':
|
'@typescript-eslint/[email protected].1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 8.71.0
|
'@typescript-eslint/types': 8.71.1
|
||||||
'@typescript-eslint/visitor-keys': 8.71.0
|
'@typescript-eslint/visitor-keys': 8.71.1
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0(typescript@5.9.3)':
|
'@typescript-eslint/[email protected].1(typescript@6.0.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
typescript: 5.9.3
|
typescript: 6.0.3
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0([email protected]([email protected]))(typescript@5.9.3)':
|
'@typescript-eslint/[email protected].1([email protected]([email protected]))(typescript@6.0.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 8.71.0
|
'@typescript-eslint/types': 8.71.1
|
||||||
'@typescript-eslint/typescript-estree': 8.71.0(typescript@5.9.3)
|
'@typescript-eslint/typescript-estree': 8.71.1(typescript@6.0.3)
|
||||||
'@typescript-eslint/utils': 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
'@typescript-eslint/utils': 8.71.1([email protected]([email protected]))(typescript@6.0.3)
|
||||||
debug: 4.4.3
|
debug: 4.4.3
|
||||||
eslint: 10.12.0([email protected])
|
eslint: 10.12.0([email protected])
|
||||||
ts-api-utils: 2.5.0(typescript@5.9.3)
|
ts-api-utils: 2.5.0(typescript@6.0.3)
|
||||||
typescript: 5.9.3
|
typescript: 6.0.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0': {}
|
'@typescript-eslint/[email protected].1': {}
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0(typescript@5.9.3)':
|
'@typescript-eslint/[email protected].1(typescript@6.0.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/project-service': 8.71.0(typescript@5.9.3)
|
'@typescript-eslint/project-service': 8.71.1(typescript@6.0.3)
|
||||||
'@typescript-eslint/tsconfig-utils': 8.71.0(typescript@5.9.3)
|
'@typescript-eslint/tsconfig-utils': 8.71.1(typescript@6.0.3)
|
||||||
'@typescript-eslint/types': 8.71.0
|
'@typescript-eslint/types': 8.71.1
|
||||||
'@typescript-eslint/visitor-keys': 8.71.0
|
'@typescript-eslint/visitor-keys': 8.71.1
|
||||||
debug: 4.4.3
|
debug: 4.4.3
|
||||||
minimatch: 10.2.6
|
minimatch: 10.2.6
|
||||||
semver: 7.8.5
|
semver: 7.8.5
|
||||||
tinyglobby: 0.2.17
|
tinyglobby: 0.2.17
|
||||||
ts-api-utils: 2.5.0(typescript@5.9.3)
|
ts-api-utils: 2.5.0(typescript@6.0.3)
|
||||||
typescript: 5.9.3
|
typescript: 6.0.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0([email protected]([email protected]))(typescript@5.9.3)':
|
'@typescript-eslint/[email protected].1([email protected]([email protected]))(typescript@6.0.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/eslint-utils': 4.10.1([email protected]([email protected]))
|
'@eslint-community/eslint-utils': 4.10.1([email protected]([email protected]))
|
||||||
'@typescript-eslint/scope-manager': 8.71.0
|
'@typescript-eslint/scope-manager': 8.71.1
|
||||||
'@typescript-eslint/types': 8.71.0
|
'@typescript-eslint/types': 8.71.1
|
||||||
'@typescript-eslint/typescript-estree': 8.71.0(typescript@5.9.3)
|
'@typescript-eslint/typescript-estree': 8.71.1(typescript@6.0.3)
|
||||||
eslint: 10.12.0([email protected])
|
eslint: 10.12.0([email protected])
|
||||||
typescript: 5.9.3
|
typescript: 6.0.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/[email protected].0':
|
'@typescript-eslint/[email protected].1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 8.71.0
|
'@typescript-eslint/types': 8.71.1
|
||||||
eslint-visitor-keys: 5.0.1
|
eslint-visitor-keys: 5.0.1
|
||||||
|
|
||||||
'@vitejs/[email protected]([email protected].2(@types/[email protected])([email protected]))([email protected](typescript@5.9.3))':
|
'@vitejs/[email protected]([email protected].4(@types/[email protected])([email protected]))([email protected](typescript@6.0.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rolldown/pluginutils': 1.0.1
|
'@rolldown/pluginutils': 1.0.1
|
||||||
vite: 8.3.2(@types/[email protected])([email protected])
|
vite: 8.3.4(@types/[email protected])([email protected])
|
||||||
vue: 3.5.43(typescript@5.9.3)
|
vue: 3.5.43(typescript@6.0.3)
|
||||||
|
|
||||||
'@vitest/[email protected]([email protected].2(@types/[email protected])([email protected]))':
|
'@vitest/[email protected]([email protected].4(@types/[email protected])([email protected]))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/trace-mapping': 0.3.31
|
'@jridgewell/trace-mapping': 0.3.31
|
||||||
'@vitest/spy': 5.0.3
|
'@vitest/spy': 5.0.3
|
||||||
estree-walker: 3.0.3
|
estree-walker: 3.0.3
|
||||||
magic-string: 1.4.2
|
magic-string: 1.4.2
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
vite: 8.3.2(@types/[email protected])([email protected])
|
vite: 8.3.4(@types/[email protected])([email protected])
|
||||||
|
|
||||||
'@vitest/[email protected]': {}
|
'@vitest/[email protected]': {}
|
||||||
|
|
||||||
@@ -1911,13 +1903,13 @@ snapshots:
|
|||||||
|
|
||||||
'@volar/[email protected]': {}
|
'@volar/[email protected]': {}
|
||||||
|
|
||||||
'@volar/[email protected](typescript@5.9.3)':
|
'@volar/[email protected](typescript@6.0.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/language-core': 2.4.28
|
'@volar/language-core': 2.4.28
|
||||||
path-browserify: 1.0.1
|
path-browserify: 1.0.1
|
||||||
vscode-uri: 3.2.0
|
vscode-uri: 3.2.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
typescript: 5.9.3
|
typescript: 6.0.3
|
||||||
|
|
||||||
'@vue/[email protected]':
|
'@vue/[email protected]':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1996,40 +1988,40 @@ snapshots:
|
|||||||
|
|
||||||
'@vue/[email protected]': {}
|
'@vue/[email protected]': {}
|
||||||
|
|
||||||
'@vue/[email protected](@vue/[email protected])(@vue/[email protected])([email protected](typescript@5.9.3))':
|
'@vue/[email protected](@vue/[email protected])(@vue/[email protected])([email protected](typescript@6.0.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/compiler-dom': 3.5.43
|
'@vue/compiler-dom': 3.5.43
|
||||||
js-beautify: 2.0.3
|
js-beautify: 2.0.3
|
||||||
vue: 3.5.43(typescript@5.9.3)
|
vue: 3.5.43(typescript@6.0.3)
|
||||||
vue-component-type-helpers: 3.3.11
|
vue-component-type-helpers: 3.3.11
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@vue/server-renderer': 3.5.43
|
'@vue/server-renderer': 3.5.43
|
||||||
|
|
||||||
'@vueuse/[email protected]([email protected](typescript@5.9.3))':
|
'@vueuse/[email protected]([email protected](typescript@6.0.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/web-bluetooth': 0.0.21
|
'@types/web-bluetooth': 0.0.21
|
||||||
'@vueuse/metadata': 14.4.0
|
'@vueuse/metadata': 14.4.0
|
||||||
'@vueuse/shared': 14.4.0([email protected](typescript@5.9.3))
|
'@vueuse/shared': 14.4.0([email protected](typescript@6.0.3))
|
||||||
vue: 3.5.43(typescript@5.9.3)
|
vue: 3.5.43(typescript@6.0.3)
|
||||||
|
|
||||||
'@vueuse/[email protected]([email protected](typescript@5.9.3))':
|
'@vueuse/[email protected]([email protected](typescript@6.0.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/web-bluetooth': 0.0.21
|
'@types/web-bluetooth': 0.0.21
|
||||||
'@vueuse/metadata': 15.0.0
|
'@vueuse/metadata': 15.0.0
|
||||||
'@vueuse/shared': 15.0.0([email protected](typescript@5.9.3))
|
'@vueuse/shared': 15.0.0([email protected](typescript@6.0.3))
|
||||||
vue: 3.5.43(typescript@5.9.3)
|
vue: 3.5.43(typescript@6.0.3)
|
||||||
|
|
||||||
'@vueuse/[email protected]': {}
|
'@vueuse/[email protected]': {}
|
||||||
|
|
||||||
'@vueuse/[email protected]': {}
|
'@vueuse/[email protected]': {}
|
||||||
|
|
||||||
'@vueuse/[email protected]([email protected](typescript@5.9.3))':
|
'@vueuse/[email protected]([email protected](typescript@6.0.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
vue: 3.5.43(typescript@5.9.3)
|
vue: 3.5.43(typescript@6.0.3)
|
||||||
|
|
||||||
'@vueuse/[email protected]([email protected](typescript@5.9.3))':
|
'@vueuse/[email protected]([email protected](typescript@6.0.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
vue: 3.5.43(typescript@5.9.3)
|
vue: 3.5.43(typescript@6.0.3)
|
||||||
|
|
||||||
[email protected]: {}
|
[email protected]: {}
|
||||||
|
|
||||||
@@ -2129,7 +2121,7 @@ snapshots:
|
|||||||
|
|
||||||
[email protected]: {}
|
[email protected]: {}
|
||||||
|
|
||||||
[email protected](@typescript-eslint/[email protected].0([email protected]([email protected]))(typescript@5.9.3))([email protected]([email protected]))([email protected]([email protected]([email protected]))):
|
[email protected](@typescript-eslint/[email protected].1([email protected]([email protected]))(typescript@6.0.3))([email protected]([email protected]))([email protected]([email protected]([email protected]))):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/eslint-utils': 4.10.1([email protected]([email protected]))
|
'@eslint-community/eslint-utils': 4.10.1([email protected]([email protected]))
|
||||||
eslint: 10.12.0([email protected])
|
eslint: 10.12.0([email protected])
|
||||||
@@ -2140,7 +2132,7 @@ snapshots:
|
|||||||
vue-eslint-parser: 10.4.1([email protected]([email protected]))
|
vue-eslint-parser: 10.4.1([email protected]([email protected]))
|
||||||
xml-name-validator: 5.0.0
|
xml-name-validator: 5.0.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@typescript-eslint/parser': 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
'@typescript-eslint/parser': 8.71.1([email protected]([email protected]))(typescript@6.0.3)
|
||||||
|
|
||||||
[email protected]:
|
[email protected]:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -2260,7 +2252,7 @@ snapshots:
|
|||||||
|
|
||||||
[email protected]: {}
|
[email protected]: {}
|
||||||
|
|
||||||
[email protected].5:
|
[email protected].6:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 26.6.4
|
'@types/node': 26.6.4
|
||||||
'@types/whatwg-mimetype': 3.0.2
|
'@types/whatwg-mimetype': 3.0.2
|
||||||
@@ -2498,13 +2490,13 @@ snapshots:
|
|||||||
|
|
||||||
[email protected]: {}
|
[email protected]: {}
|
||||||
|
|
||||||
[email protected](@vue/[email protected])(typescript@5.9.3)([email protected](typescript@5.9.3)):
|
[email protected](@vue/[email protected])(typescript@6.0.3)([email protected](typescript@6.0.3)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/devtools-api': 8.2.1
|
'@vue/devtools-api': 8.2.1
|
||||||
nostics: 1.3.0
|
nostics: 1.3.0
|
||||||
vue: 3.5.43(typescript@5.9.3)
|
vue: 3.5.43(typescript@6.0.3)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
typescript: 5.9.3
|
typescript: 6.0.3
|
||||||
|
|
||||||
[email protected]:
|
[email protected]:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -2517,6 +2509,12 @@ snapshots:
|
|||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
source-map-js: 1.2.2
|
source-map-js: 1.2.2
|
||||||
|
|
||||||
|
[email protected]:
|
||||||
|
dependencies:
|
||||||
|
nanoid: 3.3.19
|
||||||
|
picocolors: 1.1.1
|
||||||
|
source-map-js: 1.2.2
|
||||||
|
|
||||||
[email protected]: {}
|
[email protected]: {}
|
||||||
|
|
||||||
[email protected]: {}
|
[email protected]: {}
|
||||||
@@ -2529,21 +2527,18 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
hookified: 2.2.0
|
hookified: 2.2.0
|
||||||
|
|
||||||
[email protected]0.5([email protected](typescript@5.9.3)):
|
[email protected]1.0([email protected](typescript@6.0.3)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@floating-ui/dom': 1.8.0
|
'@floating-ui/vue': 2.0.1([email protected]([email protected]))
|
||||||
'@floating-ui/vue': 1.1.11([email protected]([email protected]))
|
|
||||||
'@internationalized/date': 3.12.4
|
'@internationalized/date': 3.12.4
|
||||||
'@internationalized/number': 3.6.8
|
'@internationalized/number': 3.6.8
|
||||||
'@tanstack/vue-virtual': 3.13.39([email protected](typescript@5.9.3))
|
'@tanstack/vue-virtual': 3.13.39([email protected](typescript@6.0.3))
|
||||||
'@vueuse/core': 14.4.0([email protected](typescript@5.9.3))
|
'@vueuse/core': 14.4.0([email protected](typescript@6.0.3))
|
||||||
'@vueuse/shared': 14.4.0([email protected](typescript@5.9.3))
|
'@vueuse/shared': 14.4.0([email protected](typescript@6.0.3))
|
||||||
aria-hidden: 1.2.6
|
aria-hidden: 1.2.6
|
||||||
defu: 6.1.7
|
defu: 6.1.7
|
||||||
ohash: 2.0.12
|
ohash: 2.0.12
|
||||||
vue: 3.5.43(typescript@5.9.3)
|
vue: 3.5.43(typescript@6.0.3)
|
||||||
transitivePeerDependencies:
|
|
||||||
- '@vue/composition-api'
|
|
||||||
|
|
||||||
[email protected]:
|
[email protected]:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -2593,9 +2588,9 @@ snapshots:
|
|||||||
fdir: 6.5.0([email protected])
|
fdir: 6.5.0([email protected])
|
||||||
picomatch: 4.0.7
|
picomatch: 4.0.7
|
||||||
|
|
||||||
[email protected](typescript@5.9.3):
|
[email protected](typescript@6.0.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
typescript: 5.9.3
|
typescript: 6.0.3
|
||||||
|
|
||||||
[email protected]: {}
|
[email protected]: {}
|
||||||
|
|
||||||
@@ -2603,18 +2598,18 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
prelude-ls: 1.2.1
|
prelude-ls: 1.2.1
|
||||||
|
|
||||||
[email protected].0([email protected]([email protected]))(typescript@5.9.3):
|
[email protected].1([email protected]([email protected]))(typescript@6.0.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/eslint-plugin': 8.71.0(@typescript-eslint/[email protected].0([email protected]([email protected]))(typescript@5.9.3))([email protected]([email protected]))(typescript@5.9.3)
|
'@typescript-eslint/eslint-plugin': 8.71.1(@typescript-eslint/[email protected].1([email protected]([email protected]))(typescript@6.0.3))([email protected]([email protected]))(typescript@6.0.3)
|
||||||
'@typescript-eslint/parser': 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
'@typescript-eslint/parser': 8.71.1([email protected]([email protected]))(typescript@6.0.3)
|
||||||
'@typescript-eslint/typescript-estree': 8.71.0(typescript@5.9.3)
|
'@typescript-eslint/typescript-estree': 8.71.1(typescript@6.0.3)
|
||||||
'@typescript-eslint/utils': 8.71.0([email protected]([email protected]))(typescript@5.9.3)
|
'@typescript-eslint/utils': 8.71.1([email protected]([email protected]))(typescript@6.0.3)
|
||||||
eslint: 10.12.0([email protected])
|
eslint: 10.12.0([email protected])
|
||||||
typescript: 5.9.3
|
typescript: 6.0.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
typescript@5.9.3: {}
|
typescript@6.0.3: {}
|
||||||
|
|
||||||
[email protected]: {}
|
[email protected]: {}
|
||||||
|
|
||||||
@@ -2624,11 +2619,11 @@ snapshots:
|
|||||||
|
|
||||||
[email protected]: {}
|
[email protected]: {}
|
||||||
|
|
||||||
[email protected].2(@types/[email protected])([email protected]):
|
[email protected].4(@types/[email protected])([email protected]):
|
||||||
dependencies:
|
dependencies:
|
||||||
lightningcss: 1.33.0
|
lightningcss: 1.33.0
|
||||||
picomatch: 4.0.7
|
picomatch: 4.0.7
|
||||||
postcss: 8.5.28
|
postcss: 8.5.29
|
||||||
rolldown: 1.2.12
|
rolldown: 1.2.12
|
||||||
tinyglobby: 0.2.17
|
tinyglobby: 0.2.17
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
@@ -2636,10 +2631,10 @@ snapshots:
|
|||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
jiti: 2.7.0
|
jiti: 2.7.0
|
||||||
|
|
||||||
[email protected](@types/[email protected])([email protected].5)([email protected].2(@types/[email protected])([email protected])):
|
[email protected](@types/[email protected])([email protected].6)([email protected].4(@types/[email protected])([email protected])):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/chai': 5.2.3
|
'@types/chai': 5.2.3
|
||||||
'@vitest/mocker': 5.0.3([email protected].2(@types/[email protected])([email protected]))
|
'@vitest/mocker': 5.0.3([email protected].4(@types/[email protected])([email protected]))
|
||||||
chai: 6.3.0
|
chai: 6.3.0
|
||||||
es-module-lexer: 2.3.2
|
es-module-lexer: 2.3.2
|
||||||
expect-type: 1.4.0
|
expect-type: 1.4.0
|
||||||
@@ -2650,11 +2645,11 @@ snapshots:
|
|||||||
tinybench: 6.1.4
|
tinybench: 6.1.4
|
||||||
tinyexec: 1.3.0
|
tinyexec: 1.3.0
|
||||||
tinyglobby: 0.2.17
|
tinyglobby: 0.2.17
|
||||||
vite: 8.3.2(@types/[email protected])([email protected])
|
vite: 8.3.4(@types/[email protected])([email protected])
|
||||||
why-is-node-running: 3.2.1
|
why-is-node-running: 3.2.1
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 26.6.4
|
'@types/node': 26.6.4
|
||||||
happy-dom: 20.14.5
|
happy-dom: 20.14.6
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- msw
|
- msw
|
||||||
|
|
||||||
@@ -2662,10 +2657,6 @@ snapshots:
|
|||||||
|
|
||||||
[email protected]: {}
|
[email protected]: {}
|
||||||
|
|
||||||
[email protected]([email protected]([email protected])):
|
|
||||||
dependencies:
|
|
||||||
vue: 3.5.43([email protected])
|
|
||||||
|
|
||||||
[email protected]([email protected]([email protected])):
|
[email protected]([email protected]([email protected])):
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.4.3
|
debug: 4.4.3
|
||||||
@@ -2678,13 +2669,13 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
[email protected](typescript@5.9.3):
|
[email protected](typescript@6.0.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/typescript': 2.4.28(typescript@5.9.3)
|
'@volar/typescript': 2.4.28(typescript@6.0.3)
|
||||||
'@vue/language-core': 3.3.12
|
'@vue/language-core': 3.3.12
|
||||||
typescript: 5.9.3
|
typescript: 6.0.3
|
||||||
|
|
||||||
[email protected](typescript@5.9.3):
|
[email protected](typescript@6.0.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/compiler-dom': 3.5.43
|
'@vue/compiler-dom': 3.5.43
|
||||||
'@vue/compiler-sfc': 3.5.43
|
'@vue/compiler-sfc': 3.5.43
|
||||||
@@ -2692,7 +2683,7 @@ snapshots:
|
|||||||
'@vue/server-renderer': 3.5.43
|
'@vue/server-renderer': 3.5.43
|
||||||
'@vue/shared': 3.5.43
|
'@vue/shared': 3.5.43
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
typescript: 5.9.3
|
typescript: 6.0.3
|
||||||
|
|
||||||
[email protected]: {}
|
[email protected]: {}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"description": "pnpm 11 cannot switch to the pnpm 12 native binary: npx runs it with node",
|
||||||
|
"matchDepTypes": ["packageManager"],
|
||||||
|
"matchPackageNames": ["pnpm"],
|
||||||
|
"allowedVersions": "<12"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
+2
-2
@@ -116,7 +116,7 @@ onBeforeUnmount(() => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mt-10 grid grid-cols-[minmax(0,1fr)] gap-x-10 gap-y-10 sm:mt-14 lg:grid-cols-[minmax(0,1fr)_24rem] 2xl:grid-cols-[minmax(0,1fr)_28rem]"
|
class="mt-10 grid grid-cols-[minmax(0,1fr)] gap-x-10 gap-y-10 sm:mt-14 xl:grid-cols-[minmax(0,1fr)_24rem] 2xl:grid-cols-[minmax(0,1fr)_28rem]"
|
||||||
>
|
>
|
||||||
<AttentionList
|
<AttentionList
|
||||||
ref="list"
|
ref="list"
|
||||||
@@ -133,7 +133,7 @@ onBeforeUnmount(() => {
|
|||||||
@clear="store.clearFilters()"
|
@clear="store.clearFilters()"
|
||||||
@refresh="store.refreshRepo"
|
@refresh="store.refreshRepo"
|
||||||
/>
|
/>
|
||||||
<aside class="lg:sticky lg:top-6 lg:self-start">
|
<aside class="xl:sticky xl:top-6 xl:self-start">
|
||||||
<ProjectList
|
<ProjectList
|
||||||
:repos="visibleRepos"
|
:repos="visibleRepos"
|
||||||
:total="state.repos.length"
|
:total="state.repos.length"
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ const LABEL = { crit: 'Critical', warn: 'Warning', ok: 'Healthy' } as const
|
|||||||
<ul
|
<ul
|
||||||
v-else
|
v-else
|
||||||
ref="scroller"
|
ref="scroller"
|
||||||
class="border-border bg-surface divide-border max-h-[70vh] divide-y overflow-y-auto rounded-lg border [scrollbar-color:var(--border)_transparent] [scrollbar-width:thin] lg:max-h-[calc(100vh-7rem)]"
|
class="border-border bg-surface divide-border max-h-[70vh] divide-y overflow-y-auto rounded-lg border [scrollbar-color:var(--border)_transparent] [scrollbar-width:thin] xl:max-h-[calc(100vh-7rem)]"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
v-for="repo in visible"
|
v-for="repo in visible"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { faSpinner } from '@fortawesome/free-solid-svg-icons'
|
import { faScrewdriverWrench, faSpinner } from '@fortawesome/free-solid-svg-icons'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
@@ -44,14 +44,18 @@ function press(a: ActionDef): void {
|
|||||||
<div class="mt-2 flex flex-wrap items-center gap-2" data-test="row-actions">
|
<div class="mt-2 flex flex-wrap items-center gap-2" data-test="row-actions">
|
||||||
<template v-for="a in row.actions" :key="a.id">
|
<template v-for="a in row.actions" :key="a.id">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
size="sm"
|
||||||
size="xs"
|
class="font-semibold shadow-sm"
|
||||||
:disabled="busy(a)"
|
:disabled="busy(a)"
|
||||||
:aria-busy="busy(a)"
|
:aria-busy="busy(a)"
|
||||||
:data-test="`action-${a.id}`"
|
:data-test="`action-${a.id}`"
|
||||||
@click="press(a)"
|
@click="press(a)"
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon v-if="busy(a)" :icon="faSpinner" spin aria-hidden="true" />
|
<FontAwesomeIcon
|
||||||
|
:icon="busy(a) ? faSpinner : faScrewdriverWrench"
|
||||||
|
:spin="busy(a)"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
{{ a.label }}
|
{{ a.label }}
|
||||||
</Button>
|
</Button>
|
||||||
<Badge v-if="busy(a)" variant="secondary" data-test="action-status">Sending</Badge>
|
<Badge v-if="busy(a)" variant="secondary" data-test="action-status">Sending</Badge>
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ describe('AttentionRow', () => {
|
|||||||
it('omits the age for an unknown timestamp', () => {
|
it('omits the age for an unknown timestamp', () => {
|
||||||
const w = mount(AttentionRow, {
|
const w = mount(AttentionRow, {
|
||||||
props: {
|
props: {
|
||||||
row: row({ since: '0001-01-01T00:00:00Z', kind: 'issues_stale' }),
|
row: row({ since: '0001-01-01T00:00:00Z', kind: 'issue_stale' }),
|
||||||
nowMs,
|
nowMs,
|
||||||
critSeconds: CRIT_SECONDS,
|
critSeconds: CRIT_SECONDS,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { onBeforeUnmount, onMounted, ref, type Ref } from 'vue'
|
import { onBeforeUnmount, onMounted, ref, type Ref } from 'vue'
|
||||||
|
|
||||||
/** 1 column below the breakpoint, 2 at or above it; follows the viewport live. */
|
/** 1 column below the breakpoint, 2 at or above it; follows the viewport live. */
|
||||||
export function useColumns(minWidth = '(min-width: 96rem)'): Ref<number> {
|
export function useColumns(minWidth = '(min-width: 90rem)'): Ref<number> {
|
||||||
const columns = ref(1)
|
const columns = ref(1)
|
||||||
let query: MediaQueryList | null = null
|
let query: MediaQueryList | null = null
|
||||||
const update = () => {
|
const update = () => {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const fleet = () =>
|
|||||||
}),
|
}),
|
||||||
alert({
|
alert({
|
||||||
repo: 'b/two',
|
repo: 'b/two',
|
||||||
kind: 'issues_stale',
|
kind: 'issue_stale',
|
||||||
severity: 'warn',
|
severity: 'warn',
|
||||||
subject: '4 stale issues',
|
subject: '4 stale issues',
|
||||||
url: '3',
|
url: '3',
|
||||||
@@ -62,7 +62,7 @@ describe('kindGroup', () => {
|
|||||||
['workflow_stuck', 'workflow'],
|
['workflow_stuck', 'workflow'],
|
||||||
['pr_waiting', 'pr'],
|
['pr_waiting', 'pr'],
|
||||||
['pr_checks_failing', 'pr'],
|
['pr_checks_failing', 'pr'],
|
||||||
['issues_stale', 'issue'],
|
['issue_stale', 'issue'],
|
||||||
['refresh_failed', 'data'],
|
['refresh_failed', 'data'],
|
||||||
['data_stale', 'data'],
|
['data_stale', 'data'],
|
||||||
['partial_data', 'data'],
|
['partial_data', 'data'],
|
||||||
|
|||||||
+1
-1
@@ -24,7 +24,7 @@ export const emptyFilters = (): Filters => ({
|
|||||||
export function kindGroup(kind: string): KindGroup {
|
export function kindGroup(kind: string): KindGroup {
|
||||||
if (kind.startsWith('workflow_')) return 'workflow'
|
if (kind.startsWith('workflow_')) return 'workflow'
|
||||||
if (kind.startsWith('pr_')) return 'pr'
|
if (kind.startsWith('pr_')) return 'pr'
|
||||||
if (kind === 'issues_stale') return 'issue'
|
if (kind.startsWith('issue_')) return 'issue'
|
||||||
return 'data'
|
return 'data'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -14,7 +14,9 @@ export const KIND_ICON: Record<string, IconDefinition> = {
|
|||||||
workflow_stuck: faGears,
|
workflow_stuck: faGears,
|
||||||
pr_waiting: faCodePullRequest,
|
pr_waiting: faCodePullRequest,
|
||||||
pr_checks_failing: faCodePullRequest,
|
pr_checks_failing: faCodePullRequest,
|
||||||
issues_stale: faCircleDot,
|
pr_fresh: faCodePullRequest,
|
||||||
|
issue_stale: faCircleDot,
|
||||||
|
issue_fresh: faCircleDot,
|
||||||
refresh_failed: faPlugCircleXmark,
|
refresh_failed: faPlugCircleXmark,
|
||||||
data_stale: faClockRotateLeft,
|
data_stale: faClockRotateLeft,
|
||||||
partial_data: faTriangleExclamation,
|
partial_data: faTriangleExclamation,
|
||||||
|
|||||||
+1
-2
@@ -13,8 +13,7 @@
|
|||||||
"verbatimModuleSyntax": true,
|
"verbatimModuleSyntax": true,
|
||||||
"jsx": "preserve",
|
"jsx": "preserve",
|
||||||
"types": ["vite/client", "node"],
|
"types": ["vite/client", "node"],
|
||||||
"baseUrl": ".",
|
"paths": { "@/*": ["./src/*"] }
|
||||||
"paths": { "@/*": ["src/*"] }
|
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.ts", "src/**/*.vue", "vite.config.ts"]
|
"include": ["src/**/*.ts", "src/**/*.vue", "vite.config.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user