feat: bridge adapters#23
Conversation
WalkthroughAdds three new bridge adapters (Discord, Google Chat, GitHub): CLI entrypoints, environment-driven marker helpers, full providers with webhook HTTP servers, external-API clients, delivery/ingest sequencing, and extensive unit/integration tests. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as HTTP Client
participant Server as Bridge HTTP Server
participant Runtime as bridgesdk Runtime
participant API as External API
Note over Client,API: Inbound webhook handling
Client->>Server: POST webhook (signed/auth headers)
Server->>Server: Verify signature / auth
Server->>Server: Parse payload → map to envelope
Server->>Runtime: HostAPI().IngestBridgeMessage(envelope)
Runtime-->>Server: Ack / may request delivery
Note over Server,API: Outbound delivery
Server->>Server: Resolve instance config & delivery state
Server->>Server: Enforce ordering / decide create/edit/delete
Server->>API: REST call (create/edit/delete)
API-->>Server: Response (remote id / error / retry-after)
Server->>Server: Persist delivery state & write markers
Server->>Runtime: ReportDeliveryResult
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
Actionable comments posted: 12
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@extensions/bridges/discord/provider.go`:
- Around line 875-894: The http.Server created as httpServer (used with
p.serveWebhookHTTP and Serve(ln)) has zero timeouts and can be pinned by slow
clients; set at least ReadHeaderTimeout and IdleTimeout on that http.Server
(e.g., ReadHeaderTimeout = 10*time.Second, IdleTimeout = 2*time.Minute) when
constructing it so connections can't be held indefinitely, keeping the rest of
the flow (p.server, p.serverAddr, Serve goroutine) unchanged.
- Around line 752-754: The code reads cfg.APIBaseURL into apiBaseURL (via
firstNonEmpty + normalizeURL) allowing tenant-controlled API hosts which can be
used for token exfiltration/SSRF; change this so provider_config.api_base_url is
not accepted from tenant-managed config: either only allow env/test overrides
(remove cfg.APIBaseURL from firstNonEmpty call) or validate the resolved host
against a strict allowlist of Discord hosts before using it (e.g., check the
hostname of the URL returned by normalizeURL and reject/ignore values not in the
allowlist), ensuring apiBaseURL is only set when the source is an allowed
env/test value.
- Around line 2056-2063: The isNotInitializedRPCError function should not
perform a string-based fallback; remove the strings.Contains() path and rely
only on errors.As() to detect RPC errors by their Code() value: in
isNotInitializedRPCError, keep the interface{ Code() int } extraction via
errors.As(err, &rpcErr) and return rpcErr.Code() == rpcCodeNotInitialized, and
otherwise return false so only typed RPC errors with the matching code are
considered.
- Around line 1022-1024: The handler currently ignores the incoming ctx and uses
context.Background() for inbound processing and async work; replace those with
the provided ctx when calling dispatchInboundEnvelope and when launching
goroutines so request cancellation propagates. In dispatchAsyncInboundEnvelope,
stop deriving contexts from context.Background(); instead derive them from a
provider-owned cancellable root context (e.g., p.ctx/p.cancel or add one if
missing) that is canceled in stop(), and ensure the goroutine selects on both
p.stopCh (or p.ctx.Done()) and ctx.Done() before/while calling
dispatchInboundEnvelope so in-flight work is cancelable during shutdown.
In `@extensions/bridges/gchat/provider.go`:
- Around line 1711-1827: The verification currently calls fetchGoogleX509Keys on
every request (used by verifyDirectBearerToken and verifyPubSubBearerToken) and
blocks on http.DefaultClient with no timeout; change fetchGoogleX509Keys to use
an in-memory cache keyed by certsURL with an expiry/TTL and a singleflight or
mutex to coalesce concurrent refreshes, have verification read cached keys and
only trigger a refresh when expired (or background refresh), and use a bounded
http.Client with an explicit timeout/context when performing the remote GET;
ensure errors when refreshing fall back to existing cached keys (if present) to
avoid making webhook handling dependent on the cert endpoint latency.
- Around line 826-850: The code currently accepts operator-influential URLs from
provider config (apiBaseURL, tokenURL, directCertsURL, pubsubCertsURL) when
building resolvedInstanceConfig; change this to prevent untrusted
provider_config overrides by only using operator-controlled defaults or
validated values: update the logic that sets apiBaseURL, tokenURL,
directCertsURL, and pubsubCertsURL (where firstNonEmpty(...) and
normalizeURL(...) are used) to ignore cfg values unless a flagged operator/test
mode is active, or validate them against a strict allowlist via a new helper
(e.g., isAllowedURL(url string) bool) and only accept the value if it passes
that check; ensure the resolvedInstanceConfig construction uses the
safe/validated URLs and add unit tests for both rejection and acceptance of
allowed URLs.
- Around line 972-989: The http.Server created in this block (httpServer) must
set timeouts to avoid hanging external requests: when constructing httpServer
(used with p.serveWebhookHTTP and Serve(ln)), add ReadHeaderTimeout and
IdleTimeout (and optionally ReadTimeout/WriteTimeout) with sensible durations
(e.g., ReadHeaderTimeout: 5s, IdleTimeout: 2m) instead of zero values; keep
using ln, actualAddr, and the same serve goroutine and error handling but ensure
the server struct includes these timeout fields before assigning p.server and
starting Serve.
- Around line 1067-1088: Several calls to dispatchInboundEnvelope are using
context.Background(), detaching work from request cancellation and shutdown;
replace those context.Background() calls with the real request or provider
context (e.g., use the incoming HTTP request's Context() — r.Context() — in the
webhook handler, or the provider shutdown context (p.ctx) where appropriate) so
dispatchInboundEnvelope(ctx, cfg.instanceID, item.Envelope) uses a cancellable
context; update all four call sites that currently pass context.Background()
(the branches that handle mapped direct messages and other webhook paths,
including the branch that runs when cfg.batcher is nil) to accept/forward the
correct ctx. Ensure any helper functions invoked by the handler also take and
pass the same ctx so cancellation/shutdown propagates.
In `@extensions/bridges/github/provider.go`:
- Around line 212-219: The apiFactory currently returns a new githubClient for
every call which prevents reuse of the in-memory installation-token cache;
change the implementation so each bridge instance reuses a single githubClient
(or at least a shared token cache) per resolvedInstanceConfig instead of
recreating it on every auth check/delivery. Concretely, create and store a
githubClient keyed by resolvedInstanceConfig (or attach it to the provider
instance) and have provider.apiFactory return that stored client; keep using the
same githubClient struct, http.Client with Timeout, and now: func() time.Time {
return provider.now() } when constructing the cached client.
- Around line 1014-1018: storeDeliveryState currently always inserts into
p.deliveries and never removes terminal entries, causing unbounded growth;
update githubProvider.storeDeliveryState to compute key :=
deliveryStateKey(instanceID, deliveryID), then if the incoming state is a
terminal state (implement or use an isTerminalDeliveryState helper) remove
p.deliveries[key] under p.mu (or skip insertion) instead of storing it,
otherwise store/overwrite as before; ensure p.mu locking remains around the
delete/insert to avoid races.
- Around line 587-604: The code currently checks duplicate repos via seenRepos
but does not reject shared webhook paths, which lets a payload signed by
instance A spoof instance B; add a seenWebhookPaths map and in the same
reconciliation loop (where resolveInstanceConfig returns cfg) reject duplicate
webhook paths by setting cfg.configError (similar to the repo conflict) when
cfg.webhookPath != "" and seenWebhookPaths[cfg.webhookPath] exists, e.g.
cfg.configError = fmt.Errorf("github: webhook path %q is already owned by %q and
cannot also belong to %q", cfg.webhookPath, ownerInstance, cfg.instanceID); also
record seenWebhookPaths[cfg.webhookPath] = cfg.instanceID when non-empty so
configsForPath cannot contain multiple instances for the same path (or
alternatively ensure signature verification consults configsForPath and binds
verification to payload.Repository.FullName before accepting).
- Around line 258-264: handleInitialize currently returns before afterInitialize
finishes populating p.routes which allows deliveries to proceed (with only a
500ms wait elsewhere) and fail as "unmanaged bridge instance"; fix by making
initialization wait for routes to be ready instead of launching afterInitialize
in a detached goroutine. Replace the async goroutine call around
p.afterInitialize(session) with a synchronous call or add an explicit readiness
signal (e.g., a ready channel or use p.wg/WaitGroup with a ready chan) that is
closed/fulfilled at the end of afterInitialize and have the caller (or the
delivery wait logic) block on that readiness signal instead of a fixed timeout;
apply the same change for the other occurrence mentioned (lines around the
second async block) to ensure p.routes is fully populated before
handleInitialize returns or before deliveries proceed.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 9e7c3be4-fccd-4821-bf68-d31efc355397
⛔ Files ignored due to path filters (144)
.codex/plans/2026-04-15-bridge-secret-resolution-env-refs.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/_meta.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/_tasks.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/MEMORY.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_01.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_02.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_03.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_04.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_05.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_06.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_07.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_08.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_09.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_10.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_11.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_12.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_13.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_14.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_15.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_16.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/memory/task_17.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/issues/BUG-001.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/issues/BUG-002.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/issues/BUG-003.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/issues/BUG-004.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/issues/BUG-005.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/logs/daemon-integration-package-v-after-fixes.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/daemon-integration-package-v.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/daemon-integration-package.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/daemon-live-qa.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/daemon-targeted-create-bridge-timeout.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/install-managed-focused.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/internal-extension-integration-fixed.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/internal-extension-integration-full-after-fixes.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/internal-extension-integration.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/linear-provider-focused.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/make-test-integration-fixed.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/make-test-integration.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/make-verify-final.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/make-verify.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/mock-telegram-api.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/telegram-integration-package-v.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/telegram-integration-package.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/telegram-provider-focused.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/telegram-targeted-resolve-config-timeout.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/telegram-targeted-resolve-config.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/logs/testutil-package.logis excluded by!**/*.log.compozy/tasks/bridge-adapters/qa/screenshots/bridges-page.pngis excluded by!**/*.png.compozy/tasks/bridge-adapters/qa/test-cases/SMOKE-001.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/SMOKE-002.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/SMOKE-003.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/SMOKE-004.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/SMOKE-005.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/SMOKE-006.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/SMOKE-007.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/SMOKE-008.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-001.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-002.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-003.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-004.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-005.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-006.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-007.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-008.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-009.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-010.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-011.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-012.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-013.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-014.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-015.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-016.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-017.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-018.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-019.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-FUNC-020.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-INT-001.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-INT-002.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-INT-003.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-INT-004.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-INT-005.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-INT-006.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-INT-007.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-INT-008.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-INT-009.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-INT-010.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-INT-011.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-INT-012.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-PERF-001.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-PERF-002.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-PERF-003.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-PERF-004.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-PERF-005.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-PERF-006.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-SEC-001.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-SEC-002.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-SEC-003.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-SEC-004.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-SEC-005.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-SEC-006.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-SEC-007.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-SEC-008.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-SEC-009.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-cases/TC-SEC-010.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-plans/bridge-adapters-regression.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/test-plans/bridge-adapters-test-plan.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/qa/verification-report.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_01.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_02.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_03.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_04.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_05.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_06.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_07.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_08.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_09.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_10.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_11.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_12.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_13.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_14.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_15.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_16.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/task_17.mdis excluded by!**/*.mdextensions/bridges/discord/README.mdis excluded by!**/*.mdextensions/bridges/discord/extension.tomlis excluded by!**/*.tomlextensions/bridges/gchat/extension.tomlis excluded by!**/*.tomlextensions/bridges/github/extension.tomlis excluded by!**/*.tomlextensions/bridges/linear/extension.tomlis excluded by!**/*.tomlextensions/bridges/slack/README.mdis excluded by!**/*.mdextensions/bridges/slack/extension.tomlis excluded by!**/*.tomlextensions/bridges/teams/README.mdis excluded by!**/*.mdextensions/bridges/teams/extension.tomlis excluded by!**/*.tomlextensions/bridges/telegram/README.mdis excluded by!**/*.mdextensions/bridges/telegram/extension.tomlis excluded by!**/*.tomlextensions/bridges/whatsapp/README.mdis excluded by!**/*.mdextensions/bridges/whatsapp/extension.tomlis excluded by!**/*.tomlgo.sumis excluded by!**/*.sumopenapi/agh.jsonis excluded by!**/*.jsonpackage.jsonis excluded by!**/*.jsonsdk/examples/telegram-reference/README.mdis excluded by!**/*.mdsdk/examples/telegram-reference/extension.tomlis excluded by!**/*.tomlsdk/typescript/src/generated/contracts.tsis excluded by!**/generated/**web/src/generated/agh-openapi.d.tsis excluded by!**/generated/**
📒 Files selected for processing (156)
extensions/bridges/discord/main.goextensions/bridges/discord/markers.goextensions/bridges/discord/provider.goextensions/bridges/discord/provider_test.goextensions/bridges/gchat/main.goextensions/bridges/gchat/markers.goextensions/bridges/gchat/provider.goextensions/bridges/gchat/provider_test.goextensions/bridges/github/api.goextensions/bridges/github/main.goextensions/bridges/github/markers.goextensions/bridges/github/provider.goextensions/bridges/github/provider_test.goextensions/bridges/linear/api.goextensions/bridges/linear/main.goextensions/bridges/linear/markers.goextensions/bridges/linear/provider.goextensions/bridges/linear/provider_test.goextensions/bridges/linear/runtime_test.goextensions/bridges/slack/main.goextensions/bridges/slack/markers.goextensions/bridges/slack/provider.goextensions/bridges/slack/provider_test.goextensions/bridges/teams/main.goextensions/bridges/teams/markers.goextensions/bridges/teams/provider.goextensions/bridges/teams/provider_test.goextensions/bridges/telegram/main.goextensions/bridges/telegram/markers.goextensions/bridges/telegram/provider.goextensions/bridges/telegram/provider_test.goextensions/bridges/whatsapp/main.goextensions/bridges/whatsapp/markers.goextensions/bridges/whatsapp/provider.goextensions/bridges/whatsapp/provider_test.gogo.modinternal/api/contract/bridges.gointernal/api/contract/bridges_integration_test.gointernal/api/contract/bridges_test.gointernal/api/core/bridges.gointernal/api/core/bridges_test.gointernal/api/core/conversions.gointernal/api/core/coverage_helpers_test.gointernal/api/core/errors.gointernal/api/core/errors_test.gointernal/api/httpapi/bridges_integration_test.gointernal/api/httpapi/bridges_test.gointernal/api/httpapi/httpapi_integration_test.gointernal/api/spec/spec.gointernal/api/spec/spec_test.gointernal/api/udsapi/bridges_integration_test.gointernal/api/udsapi/bridges_test.gointernal/api/udsapi/udsapi_integration_test.gointernal/bridges/delivery_broker.gointernal/bridges/delivery_broker_test.gointernal/bridges/delivery_projection_test.gointernal/bridges/delivery_types.gointernal/bridges/registry.gointernal/bridges/registry_test.gointernal/bridges/types.gointernal/bridges/types_test.gointernal/bridgesdk/batching.gointernal/bridgesdk/batching_test.gointernal/bridgesdk/cache.gointernal/bridgesdk/cache_test.gointernal/bridgesdk/dedup.gointernal/bridgesdk/dedup_test.gointernal/bridgesdk/doc.gointernal/bridgesdk/errors.gointernal/bridgesdk/errors_test.gointernal/bridgesdk/hostapi.gointernal/bridgesdk/hostapi_test.gointernal/bridgesdk/peer.gointernal/bridgesdk/peer_test.gointernal/bridgesdk/runtime.gointernal/bridgesdk/runtime_flow_test.gointernal/bridgesdk/runtime_integration_test.gointernal/bridgesdk/runtime_test.gointernal/bridgesdk/test_helpers_test.gointernal/bridgesdk/webhook.gointernal/bridgesdk/webhook_test.gointernal/cli/bridge.gointernal/cli/bridge_test.gointernal/daemon/bridge_secrets.gointernal/daemon/bridges.gointernal/daemon/bridges_test.gointernal/daemon/daemon.gointernal/daemon/daemon_integration_test.gointernal/daemon/daemon_test.gointernal/extension/bridge_delivery_integration_test.gointernal/extension/bridge_delivery_notifier_test.gointernal/extension/capability.gointernal/extension/capability_test.gointernal/extension/contract/host_api.gointernal/extension/contract/sdk.gointernal/extension/discord_provider_integration_test.gointernal/extension/gchat_provider_integration_test.gointernal/extension/github_provider_integration_test.gointernal/extension/host_api.gointernal/extension/host_api_bridges.gointernal/extension/host_api_integration_test.gointernal/extension/host_api_test.gointernal/extension/install_managed.gointernal/extension/install_managed_test.gointernal/extension/linear_provider_integration_test.gointernal/extension/manager.gointernal/extension/manager_integration_test.gointernal/extension/manager_test.gointernal/extension/manifest.gointernal/extension/manifest_integration_test.gointernal/extension/manifest_test.gointernal/extension/protocol/host_api.gointernal/extension/protocol/host_api_test.gointernal/extension/provider_conformance_matrix_integration_test.gointernal/extension/registry_test.gointernal/extension/slack_provider_integration_test.gointernal/extension/teams_provider_integration_test.gointernal/extension/telegram_provider_integration_test.gointernal/extension/telegram_reference_integration_test.gointernal/extension/whatsapp_provider_integration_test.gointernal/extensiontest/bridge_adapter_harness.gointernal/extensiontest/bridge_adapter_harness_integration_test.gointernal/extensiontest/bridge_adapter_harness_test.gointernal/extensiontest/bridge_conformance_matrix.gointernal/extensiontest/bridge_conformance_matrix_test.gointernal/observe/bridges_test.gointernal/store/globaldb/global_db.gointernal/store/globaldb/global_db_bridge.gointernal/store/globaldb/global_db_bridges_integration_test.gointernal/store/globaldb/global_db_bridges_test.gointernal/store/globaldb/global_db_extra_test.gointernal/store/globaldb/migrate_workspace.gointernal/subprocess/handshake.gointernal/subprocess/handshake_test.gointernal/testutil/testutil.gointernal/testutil/testutil_test.goscripts/postinstall.shsdk/examples/telegram-reference/main.gosdk/examples/telegram-reference/main_test.gosdk/typescript/src/extension.test.tssdk/typescript/src/host-api.test.tssdk/typescript/src/host-api.tsweb/src/routes/_app/-bridges.test.tsxweb/src/routes/_app/bridges.tsxweb/src/systems/bridges/adapters/bridges-api.test.tsweb/src/systems/bridges/components/bridge-create-dialog.test.tsxweb/src/systems/bridges/components/bridge-create-dialog.tsxweb/src/systems/bridges/components/bridge-detail-panel.test.tsxweb/src/systems/bridges/components/bridge-detail-panel.tsxweb/src/systems/bridges/hooks/use-bridge-actions.test.tsxweb/src/systems/bridges/index.tsweb/src/systems/bridges/lib/bridge-drafts.test.tsweb/src/systems/bridges/lib/bridge-drafts.tsweb/src/systems/bridges/lib/bridge-formatters.test.tsweb/src/systems/bridges/lib/bridge-formatters.tsweb/src/systems/bridges/types.ts
There was a problem hiding this comment.
Actionable comments posted: 5
♻️ Duplicate comments (1)
extensions/bridges/discord/provider.go (1)
968-969:⚠️ Potential issue | 🟠 MajorThe async interaction path is still detached from shutdown cancellation.
dispatchAsyncInboundEnvelopestill builds its owncontext.Background()timeout and only checksp.stopChonce before the host call. Once the goroutine entersdispatchInboundEnvelope, shutdown cannot cancel that work, so it can outlive provider stop. This is the same cancellation gap raised earlier, now limited to the interaction path.As per coding guidelines, "Every goroutine must have explicit ownership and shutdown via
context.Contextcancellation".Also applies to: 977-978, 1056-1072
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@extensions/bridges/discord/provider.go` around lines 968 - 969, The async interaction path spawns goroutines that use context.Background() and only check p.stopCh once, so shutdown cannot cancel ongoing work; update dispatchAsyncInboundEnvelope and any callers (the code that checks cfg.dedup.Mark and calls p.dispatchAsyncInboundEnvelope) to accept and propagate a cancellable context derived from the provider's stop/context (instead of creating context.Background()), start goroutines with that context, and ensure dispatchInboundEnvelope and its internal host calls respect that context (remove or replace any local context.Background() timeouts with ctx-aware timeouts and add select checks on ctx.Done() where p.stopCh was previously checked) so every goroutine is owned and cancels on provider shutdown.
🧹 Nitpick comments (1)
extensions/bridges/discord/provider_test.go (1)
1540-1590: Move these helpers behindt.Helper()/shared testutil instead ofunsafefield mutation.
bridgepkgToWebhookRequesthides a marshal failure, andinjectedDiscordSession/setUnexportedFieldcouple the test to privatebridgesdk.Sessionlayout viareflect+unsafe. A shared helper that takes*testing.T, callst.Helper(), and owns this setup would be much safer.As per coding guidelines, "Use
t.Helper()on test helper functions" and "Use shared test helpers frominternal/testutilandinternal/api/testutil".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@extensions/bridges/discord/provider_test.go` around lines 1540 - 1590, The helpers in this test (bridgepkgToWebhookRequest, injectedDiscordSession, setUnexportedField) are unsafe and hide errors; replace them with proper test helpers that call t.Helper(), return errors when json.Marshal fails, and avoid reflect+unsafe by using shared test utilities or exported setup functions: (1) move bridgepkgToWebhookRequest into internal testutil and change its signature to accept *testing.T and return (bridgesdk.WebhookRequest) while calling t.Helper() and failing the test on Marshal error; (2) remove injectedDiscordSession/setUnexportedField and instead add a testutil constructor that accepts a HostAPIClient and InstanceCache and initializes a bridgesdk.Session via the public API or a sanctioned test-only constructor in internal/api/testutil (also call t.Helper()); (3) update tests to import and use these new testutil helpers so no reflection/unsafe field mutation remains.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@extensions/bridges/discord/provider_test.go`:
- Around line 641-645: The test currently uses time.Sleep after calling
provider.handleInitialize, which is flaky; instead, wait deterministically for
initialization to finish by replacing the sleep with a synchronization primitive
(e.g., wait on a ready/initialized channel or a sync.WaitGroup) exposed by the
provider or returned by handleInitialize; if no such signal exists, change
provider.handleInitialize (and/or the provider struct) to signal completion (eg.
close an initDone channel or decrement a WaitGroup) and have the test block on
that signal before proceeding or asserting.
- Around line 30-1488: Convert the long, one-off tests into table-driven
subtests using t.Run("Should...") for each scenario: e.g., refactor
TestMapDiscordMessageEventRoutingAndAttachments,
TestMapDiscordInteractionPayloadsStableTargetIdentity,
TestMapDiscordReactionPayloads,
TestExecuteDiscordDeliveryValidatesEditAndDeleteOperations and similar Test*
functions into a table (slice of cases) where each case has a name like "Should
map DM with attachment" and runs as t.Run("Should ...", func(t *testing.T) {
t.Parallel(); setup reused shared test helpers (e.g.,
testDiscordManagedInstance, discordAPIFake, provider setup), execute the
scenario using the case inputs, and assert expected outputs }); keep existing
helper functions and unique identifiers (mapDiscordMessageEvent,
mapDiscordInteractionCommand, mapDiscordInteractionAction,
mapDiscordReactionEvent, executeDiscordDelivery, handleInteractionWebhook,
serveWebhookHTTP, determineInitialState, etc.) to locate logic to test and reuse
setup across cases. Ensure every new subtest uses the "Should..." naming pattern
and preserves t.Parallel() semantics and existing assertions.
In `@extensions/bridges/discord/provider.go`:
- Around line 1040-1049: Reaction events (handled via mapDiscordReactionEvent
and the MESSAGE_REACTION_ADD/REMOVE flow) are missing the DM policy check
present for MESSAGE_CREATE; before deduping (dedup.Mark) and dispatching
(dispatchInboundEnvelope) you must invoke the same allowDiscordDirectMessage
check used for messages to block reactions from disallowed DM users. Update the
reaction handling path to call allowDiscordDirectMessage with the
mapped/envelope context (the same inputs used for MESSAGE_CREATE), return an
appropriate HTTP error or no-content response when disallowed, and only proceed
to dedup.Mark and p.dispatchInboundEnvelope(mapped.Envelope) if the DM policy
allows the event.
In `@extensions/bridges/gchat/provider.go`:
- Around line 1835-1840: Add a check that the Pub/Sub JWT's email is verified:
after the existing issuerMatches and email equality checks (in the same
validation path using issuerMatches, claims.Email and
cfg.pubsubServiceAccountEmail), verify that claims.EmailVerified is true (or
non-nil and true if using a pointer) and return a descriptive error like "gchat:
pubsub bearer email %q is not verified" if not; ensure you normalize/trimsame
strings as you already do for the email comparison and place the check after
signature/audience verification so unverified email claims are rejected.
- Around line 670-678: In reportReadyIfNeeded, don't ignore the error returned
by reportState; capture its error and handle it instead of using the blank
identifier. Call reportState from reportReadyIfNeeded and if it returns an
error, log the failure (using the provider/session logger), do not update
reportedStatus to BridgeStatusReady, and return early so the instance doesn't
become stale; only set reportedStatus[p.trimmed bridgeInstanceID] =
bridgepkg.BridgeStatusReady (under p.mu) after a successful reportState call.
Ensure you remove the "_ = " usage and handle the error explicitly in
reportReadyIfNeeded.
---
Duplicate comments:
In `@extensions/bridges/discord/provider.go`:
- Around line 968-969: The async interaction path spawns goroutines that use
context.Background() and only check p.stopCh once, so shutdown cannot cancel
ongoing work; update dispatchAsyncInboundEnvelope and any callers (the code that
checks cfg.dedup.Mark and calls p.dispatchAsyncInboundEnvelope) to accept and
propagate a cancellable context derived from the provider's stop/context
(instead of creating context.Background()), start goroutines with that context,
and ensure dispatchInboundEnvelope and its internal host calls respect that
context (remove or replace any local context.Background() timeouts with
ctx-aware timeouts and add select checks on ctx.Done() where p.stopCh was
previously checked) so every goroutine is owned and cancels on provider
shutdown.
---
Nitpick comments:
In `@extensions/bridges/discord/provider_test.go`:
- Around line 1540-1590: The helpers in this test (bridgepkgToWebhookRequest,
injectedDiscordSession, setUnexportedField) are unsafe and hide errors; replace
them with proper test helpers that call t.Helper(), return errors when
json.Marshal fails, and avoid reflect+unsafe by using shared test utilities or
exported setup functions: (1) move bridgepkgToWebhookRequest into internal
testutil and change its signature to accept *testing.T and return
(bridgesdk.WebhookRequest) while calling t.Helper() and failing the test on
Marshal error; (2) remove injectedDiscordSession/setUnexportedField and instead
add a testutil constructor that accepts a HostAPIClient and InstanceCache and
initializes a bridgesdk.Session via the public API or a sanctioned test-only
constructor in internal/api/testutil (also call t.Helper()); (3) update tests to
import and use these new testutil helpers so no reflection/unsafe field mutation
remains.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 05e148b4-3ec6-46d0-ac1c-e5ce477b01ec
⛔ Files ignored due to path filters (13)
.compozy/tasks/bridge-adapters/reviews-001/_meta.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/reviews-001/issue_001.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/reviews-001/issue_002.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/reviews-001/issue_003.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/reviews-001/issue_004.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/reviews-001/issue_005.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/reviews-001/issue_006.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/reviews-001/issue_007.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/reviews-001/issue_008.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/reviews-001/issue_009.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/reviews-001/issue_010.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/reviews-001/issue_011.mdis excluded by!**/*.md.compozy/tasks/bridge-adapters/reviews-001/issue_012.mdis excluded by!**/*.md
📒 Files selected for processing (6)
extensions/bridges/discord/provider.goextensions/bridges/discord/provider_test.goextensions/bridges/gchat/provider.goextensions/bridges/gchat/provider_test.goextensions/bridges/github/provider.goextensions/bridges/github/provider_test.go
✅ Files skipped from review due to trivial changes (1)
- extensions/bridges/gchat/provider_test.go
There was a problem hiding this comment.
🧹 Nitpick comments (7)
extensions/bridges/gchat/provider.go (6)
298-304: Add compile-time interface verification forgchatBotClient.The coding guidelines require compile-time interface verification. Add a static assertion to ensure
gchatBotClientimplementsgchatAPI.As per coding guidelines: "Use compile-time interface verification:
var _ Interface = (*Type)(nil)"♻️ Proposed fix
Add after the
gchatAPIinterface definition:var _ gchatAPI = (*gchatBotClient)(nil)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@extensions/bridges/gchat/provider.go` around lines 298 - 304, Add a compile-time interface assertion that ensures gchatBotClient implements gchatAPI: insert var _ gchatAPI = (*gchatBotClient)(nil) immediately after the gchatAPI interface definition so the compiler verifies the implementation at build time; reference the gchatAPI interface and the gchatBotClient concrete type when adding this statement.
1890-1909: Consider releasing lock during remote fetch.The mutex is held during the entire remote HTTP fetch operation (line 1898). Under high concurrent load, this could cause request pile-up while waiting for a single cert refresh. Consider using singleflight or a read-then-upgrade pattern to allow concurrent cache reads while coalescing refresh operations.
This is a minor optimization concern—the current implementation is correct and the caching TTL minimizes the impact.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@extensions/bridges/gchat/provider.go` around lines 1890 - 1909, The cache lookup currently holds c.mu across the network fetch in get/refresh path; change to a read-then-upgrade pattern (or use singleflight) so the lock isn't held during c.fetchRemote: first acquire c.mu and check c.entries[trimmedURL] and expiry (using c.now()) and return if valid, otherwise release c.mu, perform keys, expiresAt, err := c.fetchRemote(ctx, trimmedURL) without the lock, then re-acquire c.mu and re-check c.entries[trimmedURL] (double-check) in case another goroutine refreshed it; if still expired or missing, store the new googleX509KeyCacheEntry{keys: keys, expiresAt: expiresAt} into c.entries[trimmedURL]; ensure error handling follows the same double-check: on fetch error re-acquire lock and return existing entry.keys if present and non-empty, else propagate err.
701-704: Consider requiring non-nil context.The function accepts a nil context and falls back to
context.Background(). Go convention is that callers should always provide a non-nil context. If this defensive check is intentional for specific call sites, consider documenting why.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@extensions/bridges/gchat/provider.go` around lines 701 - 704, The retryHostCall method on gchatProvider currently silently substitutes a nil context with context.Background(); change it to require a non-nil context: remove the fallback to context.Background(), add a guard that returns a clear error if ctx == nil (or document the requirement in the function comment and let it panic if you prefer), and update any callers of retryHostCall to pass an explicit context; reference the retryHostCall method on type gchatProvider when making these edits so the nil-context handling is enforced and the behavior is documented.
2248-2310: Consider using singleflight for token acquisition.Two concurrent calls could both perform the full token exchange if they both find the cache expired. This is safe (the work is idempotent) but could be optimized with
golang.org/x/sync/singleflightto coalesce concurrent requests for the same token.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@extensions/bridges/gchat/provider.go` around lines 2248 - 2310, The accessToken method can be optimized to coalesce concurrent token fetches using golang.org/x/sync/singleflight: add a singleflight.Group field (e.g., tokenGroup) to gchatBotClient, keep the existing short c.mu-guarded fast-path that returns cachedToken if valid, and when that misses call c.tokenGroup.Do("token", func() (interface{}, error) { ... }) to run the JWT creation + HTTP exchange exactly once for concurrent callers; inside the Do closure re-check the cache under c.mu before performing the network work, update c.cachedToken and c.tokenExpiry there, and return the token string (or error) so callers receive the result without duplicated requests.
569-571: Add justification for ignored server shutdown error.The error from
server.Shutdownis discarded. During shutdown, continuing despite an error is often the right choice, but the coding guidelines require either handling the error or documenting why it's safe to ignore.As per coding guidelines: "Never ignore errors with
_— every error must be handled or have a written justification"♻️ Proposed fix
if server != nil { - _ = server.Shutdown(shutdownCtx) + // Shutdown error is intentionally not propagated: we're already shutting down + // and need to proceed with cleanup regardless of whether the HTTP server + // stopped gracefully. + _ = server.Shutdown(shutdownCtx) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@extensions/bridges/gchat/provider.go` around lines 569 - 571, The error returned by server.Shutdown(shutdownCtx) is currently discarded; capture its return value and handle it rather than using `_`. Locate the shutdown code around the server variable and replace the ignored error with proper handling: assign err := server.Shutdown(shutdownCtx) and either log it (using the package/logger in this file) at warning/error level with context like "gchat server shutdown failed" or, if you truly intend to ignore it, add a clear comment above the call explaining why ignoring the error is safe per coding guidelines (including any assumptions about subsequent process termination or earlier cleanup) and still capture the error in a variable to satisfy linters.
946-967: Consider passing a cancellable context to the batcher.The batcher is constructed with
context.Background()which won't propagate provider shutdown signals. Whilebatcher.Close()is called during shutdown, passing a context derived from the provider's lifecycle would provide more graceful cancellation.♻️ Proposed improvement
Consider creating a provider-scoped context that's cancelled on shutdown:
if cfg.Batching.DelayMS > 0 { + batcherCtx, batcherCancel := context.WithCancel(context.Background()) + // Store batcherCancel to call during stop() batcher, err := bridgesdk.NewInboundBatcher(bridgesdk.InboundBatcherConfig{ - Context: context.Background(), + Context: batcherCtx,Alternatively, since
batcher.Close()is already called instop(), document whycontext.Background()is acceptable here.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@extensions/bridges/gchat/provider.go` around lines 946 - 967, The batcher is created with context.Background() which won't cancel on provider shutdown; change the NewInboundBatcher call to use a provider-scoped context instead (e.g., use the provider's lifecycle context field such as p.ctx or a context derived with context.WithCancel that is cancelled in stop()), so that InboundBatcherConfig.Context is tied to shutdown; update the call sites referencing bridgesdk.NewInboundBatcher, InboundBatcherConfig, and resolved.batcher accordingly and ensure existing shutdown logic (e.g., batcher.Close() in stop()) still runs.extensions/bridges/gchat/provider_test.go (1)
696-714: Consider using channel synchronization instead of sleep.Line 702 uses
time.Sleep(20 * time.Millisecond)to simulate delayed route registration. While acceptable in tests, using a channel or other synchronization primitive would be more reliable and faster.♻️ Alternative approach
waitDone := make(chan resolvedInstanceConfig, 1) +routeReady := make(chan struct{}) go func() { + <-routeReady // Wait for route to be set up cfg, waitErr := provider.waitForInstanceConfig("brg-gchat", 200*time.Millisecond) if waitErr == nil { waitDone <- cfg } }() -time.Sleep(20 * time.Millisecond) provider.mu.Lock() provider.routes["brg-gchat"] = resolvedInstanceConfig{instanceID: "brg-gchat"} provider.mu.Unlock() +close(routeReady)However, this changes the test semantics—the current test specifically validates that
waitForInstanceConfigpolls and eventually finds the config. The sleep-based approach is valid for this purpose.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@extensions/bridges/gchat/provider_test.go` around lines 696 - 714, Replace the ad-hoc time.Sleep with explicit channel synchronization: create a signaling channel (e.g., regDone := make(chan struct{})), start the goroutine that calls provider.waitForInstanceConfig("brg-gchat", 200*time.Millisecond) and sends to waitDone as before, then in a separate goroutine set provider.mu.Lock(); provider.routes["brg-gchat"]=resolvedInstanceConfig{instanceID:"brg-gchat"}; provider.mu.Unlock() only after receiving from or waiting on regDone (or close(regDone)) — remove time.Sleep(20*time.Millisecond) and use regDone to coordinate the exact moment of route registration so the test deterministically verifies waitForInstanceConfig finds the config.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@extensions/bridges/gchat/provider_test.go`:
- Around line 696-714: Replace the ad-hoc time.Sleep with explicit channel
synchronization: create a signaling channel (e.g., regDone := make(chan
struct{})), start the goroutine that calls
provider.waitForInstanceConfig("brg-gchat", 200*time.Millisecond) and sends to
waitDone as before, then in a separate goroutine set provider.mu.Lock();
provider.routes["brg-gchat"]=resolvedInstanceConfig{instanceID:"brg-gchat"};
provider.mu.Unlock() only after receiving from or waiting on regDone (or
close(regDone)) — remove time.Sleep(20*time.Millisecond) and use regDone to
coordinate the exact moment of route registration so the test deterministically
verifies waitForInstanceConfig finds the config.
In `@extensions/bridges/gchat/provider.go`:
- Around line 298-304: Add a compile-time interface assertion that ensures
gchatBotClient implements gchatAPI: insert var _ gchatAPI =
(*gchatBotClient)(nil) immediately after the gchatAPI interface definition so
the compiler verifies the implementation at build time; reference the gchatAPI
interface and the gchatBotClient concrete type when adding this statement.
- Around line 1890-1909: The cache lookup currently holds c.mu across the
network fetch in get/refresh path; change to a read-then-upgrade pattern (or use
singleflight) so the lock isn't held during c.fetchRemote: first acquire c.mu
and check c.entries[trimmedURL] and expiry (using c.now()) and return if valid,
otherwise release c.mu, perform keys, expiresAt, err := c.fetchRemote(ctx,
trimmedURL) without the lock, then re-acquire c.mu and re-check
c.entries[trimmedURL] (double-check) in case another goroutine refreshed it; if
still expired or missing, store the new googleX509KeyCacheEntry{keys: keys,
expiresAt: expiresAt} into c.entries[trimmedURL]; ensure error handling follows
the same double-check: on fetch error re-acquire lock and return existing
entry.keys if present and non-empty, else propagate err.
- Around line 701-704: The retryHostCall method on gchatProvider currently
silently substitutes a nil context with context.Background(); change it to
require a non-nil context: remove the fallback to context.Background(), add a
guard that returns a clear error if ctx == nil (or document the requirement in
the function comment and let it panic if you prefer), and update any callers of
retryHostCall to pass an explicit context; reference the retryHostCall method on
type gchatProvider when making these edits so the nil-context handling is
enforced and the behavior is documented.
- Around line 2248-2310: The accessToken method can be optimized to coalesce
concurrent token fetches using golang.org/x/sync/singleflight: add a
singleflight.Group field (e.g., tokenGroup) to gchatBotClient, keep the existing
short c.mu-guarded fast-path that returns cachedToken if valid, and when that
misses call c.tokenGroup.Do("token", func() (interface{}, error) { ... }) to run
the JWT creation + HTTP exchange exactly once for concurrent callers; inside the
Do closure re-check the cache under c.mu before performing the network work,
update c.cachedToken and c.tokenExpiry there, and return the token string (or
error) so callers receive the result without duplicated requests.
- Around line 569-571: The error returned by server.Shutdown(shutdownCtx) is
currently discarded; capture its return value and handle it rather than using
`_`. Locate the shutdown code around the server variable and replace the ignored
error with proper handling: assign err := server.Shutdown(shutdownCtx) and
either log it (using the package/logger in this file) at warning/error level
with context like "gchat server shutdown failed" or, if you truly intend to
ignore it, add a clear comment above the call explaining why ignoring the error
is safe per coding guidelines (including any assumptions about subsequent
process termination or earlier cleanup) and still capture the error in a
variable to satisfy linters.
- Around line 946-967: The batcher is created with context.Background() which
won't cancel on provider shutdown; change the NewInboundBatcher call to use a
provider-scoped context instead (e.g., use the provider's lifecycle context
field such as p.ctx or a context derived with context.WithCancel that is
cancelled in stop()), so that InboundBatcherConfig.Context is tied to shutdown;
update the call sites referencing bridgesdk.NewInboundBatcher,
InboundBatcherConfig, and resolved.batcher accordingly and ensure existing
shutdown logic (e.g., batcher.Close() in stop()) still runs.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 8cea1043-794e-404a-b689-62516b76d45d
⛔ Files ignored due to path filters (11)
.codex/plans/2026-04-15-bridge-web-e2e.mdis excluded by!**/*.mdextensions/bridges/discord/extension.tomlis excluded by!**/*.tomlextensions/bridges/gchat/extension.tomlis excluded by!**/*.tomlextensions/bridges/github/extension.tomlis excluded by!**/*.tomlextensions/bridges/linear/extension.tomlis excluded by!**/*.tomlextensions/bridges/slack/extension.tomlis excluded by!**/*.tomlextensions/bridges/teams/extension.tomlis excluded by!**/*.tomlextensions/bridges/telegram/extension.tomlis excluded by!**/*.tomlextensions/bridges/whatsapp/extension.tomlis excluded by!**/*.tomlopenapi/agh.jsonis excluded by!**/*.jsonsdk/examples/telegram-reference/extension.tomlis excluded by!**/*.toml
📒 Files selected for processing (14)
extensions/bridges/discord/provider.goextensions/bridges/discord/provider_test.goextensions/bridges/gchat/provider.goextensions/bridges/gchat/provider_test.gointernal/api/contract/bridges.gointernal/api/core/bridges.gointernal/api/httpapi/handlers_test.gointernal/api/httpapi/routes.gointernal/api/httpapi/stream_helpers_test.gointernal/api/spec/spec.gointernal/api/spec/spec_test.gointernal/api/udsapi/handlers_test.gointernal/api/udsapi/routes.gointernal/api/udsapi/stream_helpers_test.go
✅ Files skipped from review due to trivial changes (1)
- extensions/bridges/discord/provider.go
🚧 Files skipped from review as they are similar to previous changes (1)
- extensions/bridges/discord/provider_test.go
## Release v0.0.1 This PR prepares the release of version v0.0.1. ### Changelog ## 0.0.1 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.1 This PR prepares the release of version v0.0.1. ### Changelog ## 0.0.1 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.2 This PR prepares the release of version v0.0.2. ### Changelog ## 0.0.2 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release - Fix release process ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows - Improve suite speed Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.2 This PR prepares the release of version v0.0.2. ### Changelog ## 0.0.2 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release - Fix release process - Fix release sync - Decouple release dry-run npm auth - Persist web assets git auth ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows - Improve suite speed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated web assets dependency to a newer version for improved stability and performance. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/compozy/agh/pull/211?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.2 This PR prepares the release of version v0.0.2. ### Changelog ## 0.0.2 - 2026-05-27 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout - Fix release dry-run token contract ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release - Fix release process - Fix release sync - Decouple release dry-run npm auth - Persist web assets git auth - Require npm auth before release merge ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows - Improve suite speed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated dependencies to latest versions. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/compozy/agh/pull/214?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Summary by CodeRabbit