diff --git a/internal/opencode/client.go b/internal/opencode/client.go index 9b86cba..34aba0a 100644 --- a/internal/opencode/client.go +++ b/internal/opencode/client.go @@ -30,6 +30,13 @@ type Client struct { http *http.Client // единый клиент: все операции быстрые (нет блокирующего Send) } +// SessionMessagesURL возвращает URL для просмотра сообщений сессии в браузере. +// Сортировка по времени: сначала ранние (order=asc). Без credentials — пароль +// в лог не попадает. +func SessionMessagesURL(baseURL, sessionID string) string { + return baseURL + "/api/session/" + sessionID + "/message?order=asc" +} + // ClientErr — классы ошибок клиента. type ClientErr struct { Op string // "connect" | "create" | "prompt" | "messages" | "active" | "abort" diff --git a/internal/opencode/client_test.go b/internal/opencode/client_test.go index 6dde381..b560a2b 100644 --- a/internal/opencode/client_test.go +++ b/internal/opencode/client_test.go @@ -354,4 +354,13 @@ func TestClientErr_Unwrap(t *testing.T) { if !errors.As(ce, &target) { t.Fatal("expected *ClientErr") } +} + +// TestSessionMessagesURL — ссылка на сообщения сессии, сортировка по времени (сначала ранние). +func TestSessionMessagesURL(t *testing.T) { + got := SessionMessagesURL("http://127.0.0.1:4101", "sess-abc") + want := "http://127.0.0.1:4101/api/session/sess-abc/message?order=asc" + if got != want { + t.Errorf("SessionMessagesURL() = %q, want %q", got, want) + } } \ No newline at end of file diff --git a/internal/opencode/runner.go b/internal/opencode/runner.go index 35658a9..725c01f 100644 --- a/internal/opencode/runner.go +++ b/internal/opencode/runner.go @@ -84,6 +84,7 @@ func (r *Runner) Run(ctx context.Context, prompt, cwd, agent, sessionID string) return nil, fmt.Errorf("opencode: create session: %w", err) } r.logf("opencode(%s) session=%s на %s", agent, sid, srv.Addr()) + r.logf("opencode(%s) сообщения сессии: %s", agent, SessionMessagesURL(srv.Addr(), sid)) } return r.awaitVerdict(ctx, c, sid, agent, prompt)