claude-web-chat/projects.go
djuka 3283888738
All checks were successful
Tests / unit-tests (push) Successful in 51s
Inicijalna implementacija Claude Web Chat (Faza 1 - CLI mod)
- Login sa session cookie autentifikacijom
- Lista projekata iz filesystem-a
- Chat sa Claude CLI preko WebSocket-a
- Streaming NDJSON parsiranje iz CLI stdout-a
- Sesija zivi nezavisno od browsera (reconnect replay)
- Sidebar sa .md fajlovima i markdown renderovanjem
- Dark tema, htmx + Go templates
- 47 unit testova

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 05:03:40 +00:00

65 lines
1.3 KiB
Go

package main
import (
"os"
"path/filepath"
"sort"
"strings"
)
type Project struct {
Name string
Path string
Description string
HasReadme bool
}
// ListProjects returns a sorted list of projects from the given directory.
// Only directories are considered projects. Hidden directories (starting with .)
// are excluded.
func ListProjects(projectsPath string) ([]Project, error) {
entries, err := os.ReadDir(projectsPath)
if err != nil {
return nil, err
}
var projects []Project
for _, e := range entries {
if !e.IsDir() {
continue
}
name := e.Name()
if strings.HasPrefix(name, ".") {
continue
}
p := Project{
Name: name,
Path: filepath.Join(projectsPath, name),
}
// Try to read description from README.md first line
readmePath := filepath.Join(p.Path, "README.md")
if data, err := os.ReadFile(readmePath); err == nil {
p.HasReadme = true
lines := strings.SplitN(string(data), "\n", 3)
for _, line := range lines {
line = strings.TrimSpace(line)
line = strings.TrimLeft(line, "# ")
if line != "" {
p.Description = line
break
}
}
}
projects = append(projects, p)
}
sort.Slice(projects, func(i, j int) bool {
return projects[i].Name < projects[j].Name
})
return projects, nil
}