Implement initial scan logic and council formation for WHOOSH project kickoffs

- Replace incremental sync with full scan for new repositories
- Add initial_scan status to bypass Since parameter filtering
- Implement council formation detection for Design Brief issues
- Add version display to WHOOSH UI header for debugging
- Fix Docker token authentication with trailing newline removal
- Add comprehensive council orchestration with Docker Swarm integration
- Include BACKBEAT prototype integration for distributed timing
- Support council-specific agent roles and deployment strategies
- Transition repositories to active status after content discovery

Key architectural improvements:
- Full scan approach for new project detection vs incremental sync
- Council formation triggered by chorus-entrypoint labeled Design Briefs
- Proper token handling and authentication for Gitea API calls
- Support for both initial discovery and ongoing task monitoring

This enables autonomous project kickoff workflows where Design Brief issues
automatically trigger formation of specialized agent councils for new projects.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude Code
2025-09-12 09:49:36 +10:00
parent b5c0deb6bc
commit 56ea52b743
74 changed files with 17778 additions and 236 deletions

View File

@@ -11,12 +11,15 @@ import (
"strings"
"time"
"github.com/chorus-services/whoosh/internal/agents"
"github.com/chorus-services/whoosh/internal/backbeat"
"github.com/chorus-services/whoosh/internal/composer"
"github.com/chorus-services/whoosh/internal/config"
"github.com/chorus-services/whoosh/internal/council"
"github.com/chorus-services/whoosh/internal/database"
"github.com/chorus-services/whoosh/internal/gitea"
"github.com/chorus-services/whoosh/internal/monitor"
"github.com/chorus-services/whoosh/internal/orchestrator"
"github.com/chorus-services/whoosh/internal/p2p"
"github.com/chorus-services/whoosh/internal/tasks"
"github.com/go-chi/chi/v5"
@@ -27,6 +30,14 @@ import (
"github.com/rs/zerolog/log"
)
// Global version variable set by main package
var version = "development"
// SetVersion sets the global version variable
func SetVersion(v string) {
version = v
}
type Server struct {
config *config.Config
db *database.DB
@@ -35,11 +46,15 @@ type Server struct {
giteaClient *gitea.Client
webhookHandler *gitea.WebhookHandler
p2pDiscovery *p2p.Discovery
agentRegistry *agents.Registry
backbeat *backbeat.Integration
teamComposer *composer.Service
councilComposer *council.CouncilComposer
taskService *tasks.Service
giteaIntegration *tasks.GiteaIntegration
repoMonitor *monitor.Monitor
swarmManager *orchestrator.SwarmManager
agentDeployer *orchestrator.AgentDeployer
}
func NewServer(cfg *config.Config, db *database.DB) (*Server, error) {
@@ -47,19 +62,49 @@ func NewServer(cfg *config.Config, db *database.DB) (*Server, error) {
taskService := tasks.NewService(db.Pool)
giteaIntegration := tasks.NewGiteaIntegration(taskService, gitea.NewClient(cfg.GITEA), nil)
// Initialize repository monitor
repoMonitor := monitor.NewMonitor(db.Pool, cfg.GITEA)
// Initialize P2P discovery and agent registry
p2pDiscovery := p2p.NewDiscovery()
agentRegistry := agents.NewRegistry(db.Pool, p2pDiscovery)
// Initialize team composer
teamComposer := composer.NewService(db.Pool, nil) // Use default config
// Initialize council composer for project kickoffs
councilComposer := council.NewCouncilComposer(db.Pool)
// Initialize Docker Swarm orchestrator services conditionally
var swarmManager *orchestrator.SwarmManager
var agentDeployer *orchestrator.AgentDeployer
if cfg.Docker.Enabled {
var err error
swarmManager, err = orchestrator.NewSwarmManager("", "registry.home.deepblack.cloud")
if err != nil {
return nil, fmt.Errorf("failed to create swarm manager: %w", err)
}
agentDeployer = orchestrator.NewAgentDeployer(swarmManager, db.Pool, "registry.home.deepblack.cloud")
} else {
log.Warn().Msg("🐳 Docker integration disabled - council agent deployment unavailable")
}
// Initialize repository monitor with team composer, council composer, and agent deployer
repoMonitor := monitor.NewMonitor(db.Pool, cfg.GITEA, teamComposer, councilComposer, agentDeployer)
s := &Server{
config: cfg,
db: db,
giteaClient: gitea.NewClient(cfg.GITEA),
webhookHandler: gitea.NewWebhookHandler(cfg.GITEA.WebhookToken),
p2pDiscovery: p2p.NewDiscovery(),
teamComposer: composer.NewService(db.Pool, nil), // Use default config
p2pDiscovery: p2pDiscovery,
agentRegistry: agentRegistry,
teamComposer: teamComposer,
councilComposer: councilComposer,
taskService: taskService,
giteaIntegration: giteaIntegration,
repoMonitor: repoMonitor,
swarmManager: swarmManager,
agentDeployer: agentDeployer,
}
// Initialize BACKBEAT integration if enabled
@@ -206,6 +251,11 @@ func (s *Server) Start(ctx context.Context) error {
return fmt.Errorf("failed to start P2P discovery: %w", err)
}
// Start agent registry service
if err := s.agentRegistry.Start(); err != nil {
return fmt.Errorf("failed to start agent registry: %w", err)
}
// Start repository monitoring service
if s.repoMonitor != nil {
go func() {
@@ -237,6 +287,11 @@ func (s *Server) Shutdown(ctx context.Context) error {
}
}
// Stop agent registry service
if err := s.agentRegistry.Stop(); err != nil {
log.Error().Err(err).Msg("Failed to stop agent registry service")
}
// Stop P2P discovery service
if err := s.p2pDiscovery.Stop(); err != nil {
log.Error().Err(err).Msg("Failed to stop P2P discovery service")
@@ -1778,7 +1833,10 @@ func (s *Server) dashboardHandler(w http.ResponseWriter, r *http.Request) {
<body>
<div class="header">
<div class="header-content">
<div class="logo">🎭 WHOOSH</div>
<div style="display: flex; align-items: center;">
<div class="logo">🎭 WHOOSH</div>
<div style="margin-left: 16px; font-size: 14px; opacity: 0.8;">v` + version + `</div>
</div>
<div style="display: flex; align-items: center;">
<span class="status-dot"></span>
<span>System Online</span>