Files
claw-email/docs/superpowers/plans/2026-04-27-callback-base-url.md
T
thuanleandClaude Opus 4.7 c55a27d710
CI / fmt (pull_request) Failing after 4m52s
CI / test (pull_request) Successful in 10m50s
feat(mail): wire resolveThreadID into processMessage
- Add references variable to extract References header
- Replace manual inReplyTo handling with resolveThreadID call
- Maintain existing body parsing functionality
- Includes proper lambda function for database lookups

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-28 05:07:40 +07:00

4.5 KiB

Callback Base URL Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Separate server bind address from callback URL generation and default callback base to localhost when unset.

Architecture: Keep LISTEN_ADDR only for HTTP server binding. Add CALLBACK_BASE_URL in config, default to http://localhost when empty, and build dispatch callback URL from this base plus /callback.

Tech Stack: Go, stdlib net/url + strings, existing project packages.


Task 1: Add callback base URL config with localhost fallback

Files:

  • Modify: internal/config/config.go

  • Test: internal/config/config_test.go (create)

  • Step 1: Write the failing tests

func TestLoad_DefaultCallbackBaseURL_WhenUnset(t *testing.T) {
    t.Setenv("CALLBACK_BASE_URL", "")
    setRequiredEnv(t)

    cfg, err := Load()
    require.NoError(t, err)
    require.Equal(t, "http://localhost", cfg.CallbackBaseURL)
}

func TestLoad_UsesCallbackBaseURL_WhenSet(t *testing.T) {
    t.Setenv("CALLBACK_BASE_URL", "https://bridge.example.com")
    setRequiredEnv(t)

    cfg, err := Load()
    require.NoError(t, err)
    require.Equal(t, "https://bridge.example.com", cfg.CallbackBaseURL)
}
  • Step 2: Run tests to verify failure

Run: go test ./internal/config -run CallbackBaseURL -v Expected: FAIL because Config has no CallbackBaseURL field yet.

  • Step 3: Write minimal implementation
type Config struct {
    // ...existing fields...
    CallbackBaseURL string
}

cfg := &Config{
    // ...existing env reads...
    CallbackBaseURL: os.Getenv("CALLBACK_BASE_URL"),
}

if cfg.CallbackBaseURL == "" {
    cfg.CallbackBaseURL = "http://localhost"
}
  • Step 4: Run tests to verify pass

Run: go test ./internal/config -run CallbackBaseURL -v Expected: PASS.

  • Step 5: Commit
git add internal/config/config.go internal/config/config_test.go
git commit -m "feat(config): add callback base URL with localhost default"

Task 2: Build callback URL from callback base URL

Files:

  • Modify: internal/ai_client/client.go

  • Test: internal/ai_client/client_test.go (create)

  • Step 1: Write the failing tests

func TestBuildCallbackURL_DefaultLocalhostBase(t *testing.T) {
    got := buildCallbackURL("http://localhost")
    require.Equal(t, "http://localhost/callback", got)
}

func TestBuildCallbackURL_TrimsTrailingSlash(t *testing.T) {
    got := buildCallbackURL("https://bridge.example.com/")
    require.Equal(t, "https://bridge.example.com/callback", got)
}
  • Step 2: Run tests to verify failure

Run: go test ./internal/ai_client -run BuildCallbackURL -v Expected: FAIL because helper function does not exist.

  • Step 3: Write minimal implementation
func buildCallbackURL(base string) string {
    base = strings.TrimRight(base, "/")
    return base + "/callback"
}

// in Dispatch:
callbackURL := buildCallbackURL(d.cfg.CallbackBaseURL)
  • Step 4: Run tests to verify pass

Run: go test ./internal/ai_client -run BuildCallbackURL -v Expected: PASS.

  • Step 5: Commit
git add internal/ai_client/client.go internal/ai_client/client_test.go
git commit -m "fix(ai-client): use callback base URL for callback endpoint"

Task 3: Update environment docs/examples

Files:

  • Modify: .env.example

  • Modify: README.md

  • Step 1: Add config key to .env.example

LISTEN_ADDR=:8080
CALLBACK_BASE_URL=http://localhost
  • Step 2: Document purpose in README
- `LISTEN_ADDR`: local bind address for HTTP server (e.g. `:8080`)
- `CALLBACK_BASE_URL`: public base URL used to build callback endpoint; defaults to `http://localhost` when unset
  • Step 3: Run full test suite

Run: go test ./... Expected: PASS.

  • Step 4: Commit
git add .env.example README.md
git commit -m "docs: document callback base URL configuration"

Task 4: Prepare PR

Files:

  • No code changes expected

  • Step 1: Push branch

Run: git push -u origin <branch-name> Expected: branch published.

  • Step 2: Open PR with summary and test evidence

Include:

  • Problem: callback URL incorrectly built from listen addr
  • Fix: separate CALLBACK_BASE_URL with localhost fallback
  • Tests: go test ./internal/config -run CallbackBaseURL -v, go test ./internal/ai_client -run BuildCallbackURL -v, go test ./...