diff --git a/README.md b/README.md index 6fe68ac..00945b3 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,10 @@ fi When `AGORA_URL` is set, the skill tells agents to post progress, questions, blockers, verification results, and final handoffs to Agora. +The server-backed CLI commands `agora post`, `agora inbox`, and `agora status` +require `AGORA_URL` and fail when it is missing. `agora session` does not +contact the server and does not require `AGORA_URL`. + Run `agora session` once when each coding-agent session starts. The generated `AGORA_THREAD` keeps that session's posts together while replies still inherit their parent post's thread. diff --git a/internal/agoracli/cli.go b/internal/agoracli/cli.go index aa8e7cb..22a6054 100644 --- a/internal/agoracli/cli.go +++ b/internal/agoracli/cli.go @@ -130,8 +130,8 @@ func runPost(ctx context.Context, args []string, cfg Config) int { if strings.TrimSpace(*title) == "" { return usageError(fs, "--title is required") } - if skipIfNoServer(cfg) { - return 0 + if code := requireServerURL("agora post", cfg); code != -1 { + return code } threadValue := thread.value @@ -203,8 +203,8 @@ func runInbox(ctx context.Context, args []string, cfg Config) int { if strings.TrimSpace(*agent) == "" { return usageError(fs, "--agent is required") } - if skipIfNoServer(cfg) { - return 0 + if code := requireServerURL("agora inbox", cfg); code != -1 { + return code } query := url.Values{"limit": {fmt.Sprint(*limit)}} @@ -252,8 +252,8 @@ func runStatus(ctx context.Context, args []string, cfg Config) int { if !statuses[status] { return usageError(fs, "unknown status %q", status) } - if skipIfNoServer(cfg) { - return 0 + if code := requireServerURL("agora status", cfg); code != -1 { + return code } payload := map[string]any{"actor": *actor, "status": status} @@ -289,12 +289,12 @@ func usageError(fs *flag.FlagSet, format string, args ...any) int { return 2 } -func skipIfNoServer(cfg Config) bool { +func requireServerURL(command string, cfg Config) int { if strings.TrimSpace(cfg.BaseURL) != "" { - return false + return -1 } - fmt.Fprintln(cfg.stderr(), "AGORA_URL is not set; skipping Agora.") - return true + fmt.Fprintf(cfg.stderr(), "%s: AGORA_URL is required\n", command) + return 1 } func printUsage(w io.Writer) { diff --git a/internal/agoracli/cli_test.go b/internal/agoracli/cli_test.go index 8c3bd05..2b04544 100644 --- a/internal/agoracli/cli_test.go +++ b/internal/agoracli/cli_test.go @@ -302,21 +302,48 @@ func TestStatusUpdatesEvent(t *testing.T) { } } -func TestMissingURLSkipsRequest(t *testing.T) { - var stdout bytes.Buffer - var stderr bytes.Buffer - code := Run(context.Background(), []string{"post", "--type", "summary", "--title", "Started task"}, Config{ - Stdout: &stdout, - Stderr: &stderr, - }) - if code != 0 { - t.Fatalf("exit code = %d, stderr = %s", code, stderr.String()) - } - if stdout.String() != "" { - t.Fatalf("stdout = %q, want empty", stdout.String()) +func TestMissingURLFailsForServerCommands(t *testing.T) { + tests := []struct { + name string + args []string + command string + }{ + { + name: "post", + args: []string{"post", "--type", "summary", "--title", "Started task"}, + command: "agora post", + }, + { + name: "inbox", + args: []string{"inbox", "--agent", "codex"}, + command: "agora inbox", + }, + { + name: "status", + args: []string{"status", "evt-1", "acknowledged"}, + command: "agora status", + }, } - if got := stderr.String(); got != "AGORA_URL is not set; skipping Agora.\n" { - t.Fatalf("stderr = %q", got) + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var stdout bytes.Buffer + var stderr bytes.Buffer + code := Run(context.Background(), tt.args, Config{ + Stdout: &stdout, + Stderr: &stderr, + }) + if code != 1 { + t.Fatalf("exit code = %d, stderr = %s", code, stderr.String()) + } + if stdout.String() != "" { + t.Fatalf("stdout = %q, want empty", stdout.String()) + } + want := tt.command + ": AGORA_URL is required\n" + if got := stderr.String(); got != want { + t.Fatalf("stderr = %q, want %q", got, want) + } + }) } } diff --git a/skills/agora-reporting/SKILL.md b/skills/agora-reporting/SKILL.md index 6e514c1..48a67e3 100644 --- a/skills/agora-reporting/SKILL.md +++ b/skills/agora-reporting/SKILL.md @@ -7,6 +7,8 @@ description: Report coding-agent progress, questions, decisions, blockers, tests Use Agora as the shared coordination feed for human and agent work. If `AGORA_URL` is unset, skip Agora reporting without blocking the task. +The server-backed commands `post`, `inbox`, and `status` require `AGORA_URL`; +`session` does not contact the server and does not require `AGORA_URL`. ## Setup