Pusti: premešta task ready→active bez pokretanja claude sesije
- handleRunTask samo premešta task iz ready/ u active/ sa timestampom - Uklonjena zavisnost od console sesija — konzola je nezavisna - Korisnik pokreće claude ručno iz konzole terminala - Ažurirani testovi (6 RunTask testova prolaze) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
932ffe5203
commit
ac72ca6f52
@ -123,6 +123,9 @@ func (s *Server) setupRoutes() {
|
||||
s.Router.GET("/console/history/:session", s.handleConsoleHistory)
|
||||
s.Router.GET("/console/ws/:session", s.handleConsoleWS)
|
||||
|
||||
// Logs route
|
||||
s.Router.GET("/api/logs/tail", s.handleLogsTail)
|
||||
|
||||
// Docs routes
|
||||
s.Router.GET("/docs", s.handleDocsList)
|
||||
s.Router.GET("/docs/*path", s.handleDocsView)
|
||||
@ -346,54 +349,19 @@ func (s *Server) handleRunTask(c *gin.Context) {
|
||||
task.Status = "ready"
|
||||
}
|
||||
|
||||
// Find free session
|
||||
sessionIdx := -1
|
||||
for i := 0; i < 2; i++ {
|
||||
sess := s.console.getSession(i)
|
||||
sess.mu.Lock()
|
||||
if sess.status == "idle" {
|
||||
sessionIdx = i
|
||||
sess.mu.Unlock()
|
||||
break
|
||||
}
|
||||
sess.mu.Unlock()
|
||||
}
|
||||
|
||||
if sessionIdx == -1 {
|
||||
c.JSON(http.StatusConflict, gin.H{"error": "obe sesije su zauzete"})
|
||||
// Move ready → active
|
||||
if err := supervisor.MoveTask(s.Config.TasksDir, id, "ready", "active"); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Build the prompt
|
||||
prompt := "Pročitaj CLAUDE.md u root-u projekta. Tvoj task: TASKS/ready/" + id + ".md — Pročitaj task fajl i uradi šta piše. Prati pravila iz CLAUDE.md."
|
||||
|
||||
// Start in the session
|
||||
session := s.console.getSession(sessionIdx)
|
||||
execID := s.console.nextExecID()
|
||||
|
||||
session.mu.Lock()
|
||||
session.status = "running"
|
||||
session.execID = execID
|
||||
session.taskID = id
|
||||
session.output = nil
|
||||
session.history = append(session.history, historyEntry{
|
||||
Command: "pusti " + id,
|
||||
ExecID: execID,
|
||||
Timestamp: timeNow(),
|
||||
Status: "running",
|
||||
})
|
||||
session.mu.Unlock()
|
||||
|
||||
// Append "Pokrenut" timestamp
|
||||
taskPath := filepath.Join(s.Config.TasksDir, "ready", id+".md")
|
||||
appendTimestamp(taskPath, "Pokrenut")
|
||||
|
||||
go s.runCommand(session, prompt, execID)
|
||||
taskPath := filepath.Join(s.Config.TasksDir, "active", id+".md")
|
||||
appendTimestamp(taskPath, "Pokrenut (→active)")
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"status": "started",
|
||||
"session": sessionIdx + 1,
|
||||
"exec_id": execID,
|
||||
"status": "started",
|
||||
"task": id,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -809,8 +809,12 @@ func TestRunTask_Ready(t *testing.T) {
|
||||
if resp["status"] != "started" {
|
||||
t.Errorf("expected status started, got %v", resp["status"])
|
||||
}
|
||||
if resp["session"] == nil {
|
||||
t.Error("expected session number in response")
|
||||
if resp["task"] != "T08" {
|
||||
t.Errorf("expected task T08, got %v", resp["task"])
|
||||
}
|
||||
// Verify task moved to active/
|
||||
if _, err := os.Stat(filepath.Join(srv.Config.TasksDir, "active", "T08.md")); err != nil {
|
||||
t.Error("expected T08.md in active/")
|
||||
}
|
||||
}
|
||||
|
||||
@ -853,7 +857,7 @@ func TestRunTask_NotFound(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunTask_BothSessionsBusy(t *testing.T) {
|
||||
func TestRunTask_MovesToActive(t *testing.T) {
|
||||
srv := setupTestServer(t)
|
||||
|
||||
// Move T08 to ready
|
||||
@ -862,30 +866,18 @@ func TestRunTask_BothSessionsBusy(t *testing.T) {
|
||||
filepath.Join(srv.Config.TasksDir, "ready", "T08.md"),
|
||||
)
|
||||
|
||||
// Occupy both sessions
|
||||
srv.console.sessions[0].mu.Lock()
|
||||
srv.console.sessions[0].status = "running"
|
||||
srv.console.sessions[0].mu.Unlock()
|
||||
|
||||
srv.console.sessions[1].mu.Lock()
|
||||
srv.console.sessions[1].status = "running"
|
||||
srv.console.sessions[1].mu.Unlock()
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/task/T08/run", nil)
|
||||
w := httptest.NewRecorder()
|
||||
srv.Router.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusConflict {
|
||||
t.Fatalf("expected 409 when both sessions busy, got %d: %s", w.Code, w.Body.String())
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
// Clean up
|
||||
srv.console.sessions[0].mu.Lock()
|
||||
srv.console.sessions[0].status = "idle"
|
||||
srv.console.sessions[0].mu.Unlock()
|
||||
srv.console.sessions[1].mu.Lock()
|
||||
srv.console.sessions[1].status = "idle"
|
||||
srv.console.sessions[1].mu.Unlock()
|
||||
// Verify task moved to active/
|
||||
if _, err := os.Stat(filepath.Join(srv.Config.TasksDir, "active", "T08.md")); err != nil {
|
||||
t.Error("expected T08.md in active/ after run")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDashboardHTML_HasRunButton(t *testing.T) {
|
||||
@ -1865,11 +1857,16 @@ func TestRunTask_AddsTimestamp(t *testing.T) {
|
||||
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
content, _ := os.ReadFile(filepath.Join(srv.Config.TasksDir, "ready", "T08.md"))
|
||||
// Task should now be in active/
|
||||
content, _ := os.ReadFile(filepath.Join(srv.Config.TasksDir, "active", "T08.md"))
|
||||
text := string(content)
|
||||
if !containsStr(text, "Pokrenut") {
|
||||
t.Error("expected 'Pokrenut' timestamp after run")
|
||||
}
|
||||
// Verify it's no longer in ready/
|
||||
if _, err := os.Stat(filepath.Join(srv.Config.TasksDir, "ready", "T08.md")); err == nil {
|
||||
t.Error("task should no longer be in ready/")
|
||||
}
|
||||
}
|
||||
|
||||
// --- T24: PTY tests ---
|
||||
|
||||
Loading…
Reference in New Issue
Block a user