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/history/:session", s.handleConsoleHistory)
|
||||||
s.Router.GET("/console/ws/:session", s.handleConsoleWS)
|
s.Router.GET("/console/ws/:session", s.handleConsoleWS)
|
||||||
|
|
||||||
|
// Logs route
|
||||||
|
s.Router.GET("/api/logs/tail", s.handleLogsTail)
|
||||||
|
|
||||||
// Docs routes
|
// Docs routes
|
||||||
s.Router.GET("/docs", s.handleDocsList)
|
s.Router.GET("/docs", s.handleDocsList)
|
||||||
s.Router.GET("/docs/*path", s.handleDocsView)
|
s.Router.GET("/docs/*path", s.handleDocsView)
|
||||||
@ -346,54 +349,19 @@ func (s *Server) handleRunTask(c *gin.Context) {
|
|||||||
task.Status = "ready"
|
task.Status = "ready"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find free session
|
// Move ready → active
|
||||||
sessionIdx := -1
|
if err := supervisor.MoveTask(s.Config.TasksDir, id, "ready", "active"); err != nil {
|
||||||
for i := 0; i < 2; i++ {
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
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"})
|
|
||||||
return
|
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
|
// Append "Pokrenut" timestamp
|
||||||
taskPath := filepath.Join(s.Config.TasksDir, "ready", id+".md")
|
taskPath := filepath.Join(s.Config.TasksDir, "active", id+".md")
|
||||||
appendTimestamp(taskPath, "Pokrenut")
|
appendTimestamp(taskPath, "Pokrenut (→active)")
|
||||||
|
|
||||||
go s.runCommand(session, prompt, execID)
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"status": "started",
|
"status": "started",
|
||||||
"session": sessionIdx + 1,
|
"task": id,
|
||||||
"exec_id": execID,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -809,8 +809,12 @@ func TestRunTask_Ready(t *testing.T) {
|
|||||||
if resp["status"] != "started" {
|
if resp["status"] != "started" {
|
||||||
t.Errorf("expected status started, got %v", resp["status"])
|
t.Errorf("expected status started, got %v", resp["status"])
|
||||||
}
|
}
|
||||||
if resp["session"] == nil {
|
if resp["task"] != "T08" {
|
||||||
t.Error("expected session number in response")
|
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)
|
srv := setupTestServer(t)
|
||||||
|
|
||||||
// Move T08 to ready
|
// Move T08 to ready
|
||||||
@ -862,30 +866,18 @@ func TestRunTask_BothSessionsBusy(t *testing.T) {
|
|||||||
filepath.Join(srv.Config.TasksDir, "ready", "T08.md"),
|
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)
|
req := httptest.NewRequest(http.MethodPost, "/task/T08/run", nil)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
srv.Router.ServeHTTP(w, req)
|
srv.Router.ServeHTTP(w, req)
|
||||||
|
|
||||||
if w.Code != http.StatusConflict {
|
if w.Code != http.StatusOK {
|
||||||
t.Fatalf("expected 409 when both sessions busy, got %d: %s", w.Code, w.Body.String())
|
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up
|
// Verify task moved to active/
|
||||||
srv.console.sessions[0].mu.Lock()
|
if _, err := os.Stat(filepath.Join(srv.Config.TasksDir, "active", "T08.md")); err != nil {
|
||||||
srv.console.sessions[0].status = "idle"
|
t.Error("expected T08.md in active/ after run")
|
||||||
srv.console.sessions[0].mu.Unlock()
|
}
|
||||||
srv.console.sessions[1].mu.Lock()
|
|
||||||
srv.console.sessions[1].status = "idle"
|
|
||||||
srv.console.sessions[1].mu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDashboardHTML_HasRunButton(t *testing.T) {
|
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())
|
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)
|
text := string(content)
|
||||||
if !containsStr(text, "Pokrenut") {
|
if !containsStr(text, "Pokrenut") {
|
||||||
t.Error("expected 'Pokrenut' timestamp after run")
|
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 ---
|
// --- T24: PTY tests ---
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user