diff --git a/AGENTS.md b/AGENTS.md index 0f8ef13..a876ff7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -56,6 +56,8 @@ Determine the task type and apply the corresponding format: - [Critical defaults](guides/critical-defaults.md) - mandatory rules for every repository task. +- [Git workflow](guides/git-workflow.md) - branch policy, PR-only workflow, + branch naming, and rules for AI agents before editing. - [Coding agent workflow](.claude/rules/delegation.md) - default workflow for all file-editing tasks (delegation, model routing, verification). - [Project overview](guides/project-overview.md) - domain model, public API @@ -73,6 +75,7 @@ Determine the task type and apply the corresponding format: See [guides/critical-defaults.md](guides/critical-defaults.md) for the full list of mandatory pre-edit, compatibility, testing, and git rules. +For branch and PR policy, also see [guides/git-workflow.md](guides/git-workflow.md). ## Provenance and Honesty diff --git a/guides/critical-defaults.md b/guides/critical-defaults.md index e8dc73d..b13ed1d 100644 --- a/guides/critical-defaults.md +++ b/guides/critical-defaults.md @@ -28,4 +28,4 @@ Mandatory rules for every repository task. ## Git -- All changes reach `main` through PRs; do not push directly to `main` unless the user explicitly overrides this rule. +See [Git workflow](git-workflow.md) for the full branch and PR policy. diff --git a/include/kurlyk/http/HttpClient.hpp b/include/kurlyk/http/HttpClient.hpp index c8b6db6..e199522 100644 --- a/include/kurlyk/http/HttpClient.hpp +++ b/include/kurlyk/http/HttpClient.hpp @@ -200,6 +200,21 @@ namespace kurlyk { void set_auth_provider(std::shared_ptr provider) { m_auth_provider = provider; } + + /// \brief Removes the current authentication provider from this client. + void clear_auth_provider() { + m_auth_provider.reset(); + } + + /// \brief Returns whether this client has an active authentication provider. + bool has_auth_provider() const { + return m_auth_provider != nullptr; + } + + /// \brief Returns the current authentication provider, or nullptr if none is set. + std::shared_ptr auth_provider() const { + return m_auth_provider; + } #endif /// \brief Assigns an existing rate limit to future requests by ID. diff --git a/include/kurlyk/http/HttpRequestManager.hpp b/include/kurlyk/http/HttpRequestManager.hpp index 68aa7f6..ebad7b5 100644 --- a/include/kurlyk/http/HttpRequestManager.hpp +++ b/include/kurlyk/http/HttpRequestManager.hpp @@ -239,8 +239,18 @@ namespace kurlyk { if (callback) callback(); return; } - std::lock_guard lock(m_mutex); - m_groups_to_cancel[group_id].push_back(std::move(callback)); + bool invoke_now = false; + { + std::lock_guard lock(m_mutex); + if (group_request_count_unlocked(group_id) == 0) { + invoke_now = true; + } else { + m_groups_to_cancel[group_id].push_back(std::move(callback)); + } + } + if (invoke_now && callback) { + callback(); + } } /// \brief Processes all requests in the manager. diff --git a/tests/integration/http_client_wait_requests_main.cpp b/tests/integration/http_client_wait_requests_main.cpp index 4413177..017ebce 100644 --- a/tests/integration/http_client_wait_requests_main.cpp +++ b/tests/integration/http_client_wait_requests_main.cpp @@ -321,6 +321,26 @@ int main() { client.reset(); } + // --- Test 9: wait_requests() on empty group returns immediately --- + { + ProcessorGuard pg; + auto client = std::make_unique(base_url); + auto t0 = std::chrono::steady_clock::now(); + client->wait_requests(); + auto dt = std::chrono::steady_clock::now() - t0; + require(dt < std::chrono::milliseconds(50), + "wait_requests() on empty group must return immediately"); + client.reset(); + } + + // --- Test 10: wait_requests_for() on empty group returns true immediately --- + { + auto client = std::make_unique(base_url); + bool done = client->wait_requests_for(std::chrono::milliseconds(10)); + require(done, "wait_requests_for() on empty group must return true immediately"); + client.reset(); + } + server.stop(); server_thread.join();