f99010fae1
Desktop Artifacts / Desktop Build (Linux) (push) Waiting to run
Desktop Artifacts / Desktop Build (Windows) (push) Waiting to run
Desktop Artifacts / Desktop Build (Linux (arm64)) (push) Waiting to run
Desktop Artifacts (macOS) / Desktop Build (macOS (aarch64)) (push) Waiting to run
Desktop Artifacts (macOS) / Desktop Build (macOS (x86_64)) (push) Waiting to run
CI / lint (push) Failing after 1s
CI / frontend (push) Failing after 1s
CI / scripts (push) Failing after 1s
CI / Go Test (ubuntu-latest) (push) Failing after 0s
CI / frontend-node-25 (push) Failing after 1s
CI / docs (push) Failing after 0s
CI / coverage (push) Failing after 0s
CI / e2e (push) Failing after 0s
Docker / build-and-push (push) Failing after 1s
CI / integration (push) Failing after 4m43s
CI / Go Test (windows-latest) (push) Has been cancelled
CI / Desktop Unit Tests (Windows) (push) Has been cancelled
113 lines
2.4 KiB
Go
113 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"go.kenn.io/agentsview/internal/config"
|
|
"go.kenn.io/agentsview/internal/db"
|
|
)
|
|
|
|
var projectsHTTPClient = &http.Client{Timeout: 30 * time.Second}
|
|
|
|
func runProjects(jsonOutput bool) {
|
|
appCfg, err := config.LoadMinimal()
|
|
if err != nil {
|
|
log.Fatalf("loading config: %v", err)
|
|
}
|
|
|
|
ctx := context.Background()
|
|
tr, err := ensureTransport(&appCfg, transportIntentRead, 0)
|
|
if err != nil {
|
|
fatal("resolving transport: %v", err)
|
|
}
|
|
if tr.Mode != transportHTTP {
|
|
fatal("resolving transport: expected daemon transport")
|
|
}
|
|
projects, err := fetchHTTPProjects(
|
|
ctx, tr, appCfg.AuthToken, false, false,
|
|
)
|
|
if err != nil {
|
|
fatal("listing projects: %v", err)
|
|
}
|
|
|
|
writeProjects(projects, jsonOutput)
|
|
}
|
|
|
|
func fetchHTTPProjects(
|
|
ctx context.Context,
|
|
tr transport,
|
|
authToken string,
|
|
excludeOneShot bool,
|
|
excludeAutomated bool,
|
|
) ([]db.ProjectInfo, error) {
|
|
q := url.Values{}
|
|
q.Set("include_one_shot", strconv.FormatBool(!excludeOneShot))
|
|
q.Set("include_automated", strconv.FormatBool(!excludeAutomated))
|
|
endpoint := strings.TrimSuffix(tr.URL, "/") +
|
|
"/api/v1/projects?" + q.Encode()
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if authToken != "" {
|
|
req.Header.Set("Authorization", "Bearer "+authToken)
|
|
}
|
|
resp, err := projectsHTTPClient.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode != http.StatusOK {
|
|
body, _ := io.ReadAll(resp.Body)
|
|
return nil, fmt.Errorf(
|
|
"projects: HTTP %d: %s",
|
|
resp.StatusCode, strings.TrimSpace(string(body)),
|
|
)
|
|
}
|
|
var out struct {
|
|
Projects []db.ProjectInfo `json:"projects"`
|
|
}
|
|
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
|
|
return nil, err
|
|
}
|
|
return out.Projects, nil
|
|
}
|
|
|
|
func writeProjects(projects []db.ProjectInfo, jsonOutput bool) {
|
|
if jsonOutput {
|
|
if projects == nil {
|
|
projects = []db.ProjectInfo{}
|
|
}
|
|
enc := json.NewEncoder(os.Stdout)
|
|
enc.SetIndent("", " ")
|
|
if err := enc.Encode(projects); err != nil {
|
|
fatal("encoding json: %v", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
if len(projects) == 0 {
|
|
fmt.Println("No projects found.")
|
|
return
|
|
}
|
|
|
|
fmt.Printf("%-40s %s\n", "PROJECT", "SESSIONS")
|
|
for _, p := range projects {
|
|
name := p.Name
|
|
if name == "" {
|
|
name = "(none)"
|
|
}
|
|
fmt.Printf("%-40s %d\n", name, p.SessionCount)
|
|
}
|
|
}
|