Skip to content

feat: add multi-provider source-control support - #30

Merged
kodiakhq[bot] merged 6 commits into
mainfrom
claude/issue-14-implementation-9n4972
Aug 13, 2026
Merged

feat: add multi-provider source-control support#30
kodiakhq[bot] merged 6 commits into
mainfrom
claude/issue-14-implementation-9n4972

Conversation

@RedStar071

@RedStar071RedStar071 commented Aug 13, 2026

Copy link
Copy Markdown
Member

Evolve the GitHub-only adapter boundary into a provider-neutral
source-control package with adapters for GitHub / GitHub Enterprise,
GitLab / Self-Managed, Bitbucket Cloud, Bitbucket Data Center, and
Gitea / Forgejo, per the v0.5 milestone (#14).

Boundary: packages/github becomes packages/source-control. Shared
contracts (SourceControlProvider, ProviderCapabilities,
ChangeRequestRef, RunOutcome, StatusPublication) keep provider payload
shapes, event names, URLs, and credentials at the integration boundary;
the agent runtime keeps consuming only @agent-zero/shared types.

Safety: every adapter authenticates the raw webhook body before
parsing (HMAC-SHA256 or constant-time shared-token compare), bounds and
attributes untrusted feedback, defaults parsed events to observe mode
so a webhook can never escalate a run, and suppresses self-replies via
ignoreAuthors. Status credentials travel only as Authorization headers
and are redacted from raised errors. Capability detection makes
unsupported features degrade explicitly: providers without a neutral or
action-required status report the mapping in StatusPublication.degraded
instead of lying, GitLab's missing diff base yields no fabricated
pull-request range, and bodyless change-request signals are ignored
rather than invented.

The oRPC server now routes inbound deliveries by provider headers, so
one deployment can accept webhooks from several configured providers,
each with its own secret; evidence publishing resolves the adapter from
the change-request reference and its per-provider token variable.

A framework-free conformance suite runs every adapter through the same
recognition, forgery-rejection, normalization, self-reply, junk-payload,
observe-by-default, credential-hygiene, and explicit-degradation checks
from authentic signed fixtures.

Verification: 121 package tests (conformance plus adapter suites) and
68 server tests pass; typecheck, oxlint type-aware lint, oxfmt, build,
and check:repo pass locally for the affected packages.

Closes#14

Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01MJQxEwqaaP4aMG4E7yeaky


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Confidence Score: 5/5

No blocking failure remains.

Execution confirmed that Bitbucket Cloud and Bitbucket Data Center independently resolve their configured credentials and use them only for their respective status-publication requests.

T-Rex T-Rex Logs

What T-Rex did

  • Executed a focused runtime harness that compared the prior Bitbucket token mapping with the current environment resolution and invoked both Bitbucket status adapters.
  • The results show that the prior mapping resolved both Bitbucket products from one credential, while the current mapping resolves distinct Cloud and Data Center values and routes each to its matching status endpoint.
  • The router and source-control conformance suites were run and all tests passed (43 router tests and 55 source-control conformance tests).

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (6): Last reviewed commit: "fix(lockfile): restore missing apps/dash..." | Re-trigger Greptile

Evolve the GitHub-only adapter boundary into a provider-neutral
source-control package with adapters for GitHub / GitHub Enterprise,
GitLab / Self-Managed, Bitbucket Cloud, Bitbucket Data Center, and
Gitea / Forgejo, per the v0.5 milestone (#14).
Boundary: packages/github becomes packages/source-control. Shared
contracts (SourceControlProvider, ProviderCapabilities,
ChangeRequestRef, RunOutcome, StatusPublication) keep provider payload
shapes, event names, URLs, and credentials at the integration boundary;
the agent runtime keeps consuming only @agent-zero/shared types.
Safety: every adapter authenticates the raw webhook body before
parsing (HMAC-SHA256 or constant-time shared-token compare), bounds and
attributes untrusted feedback, defaults parsed events to observe mode
so a webhook can never escalate a run, and suppresses self-replies via
ignoreAuthors. Status credentials travel only as Authorization headers
and are redacted from raised errors. Capability detection makes
unsupported features degrade explicitly: providers without a neutral or
action-required status report the mapping in StatusPublication.degraded
instead of lying, GitLab's missing diff base yields no fabricated
pull-request range, and bodyless change-request signals are ignored
rather than invented.
The oRPC server now routes inbound deliveries by provider headers, so
one deployment can accept webhooks from several configured providers,
each with its own secret; evidence publishing resolves the adapter from
the change-request reference and its per-provider token variable.
A framework-free conformance suite runs every adapter through the same
recognition, forgery-rejection, normalization, self-reply, junk-payload,
observe-by-default, credential-hygiene, and explicit-degradation checks
from authentic signed fixtures.
Verification: 121 package tests (conformance plus adapter suites) and
68 server tests pass; typecheck, oxlint type-aware lint, oxfmt, build,
and check:repo pass locally for the affected packages.
Closes#14
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MJQxEwqaaP4aMG4E7yeaky
Comment threadapps/server/src/router.ts Outdated
Bitbucket Cloud and Bitbucket Data Center both resolved status
credentials from BITBUCKET_TOKEN, so a deployment connecting both
products with distinct credentials could not configure them
independently. Split the mapping into BITBUCKET_CLOUD_TOKEN and
BITBUCKET_DATA_CENTER_TOKEN, update the provider docs, and add a
regression test asserting the two resolve independently.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MJQxEwqaaP4aMG4E7yeaky
greptile-apps[bot]
greptile-appsBot previously approved these changes Aug 13, 2026
packages/github was renamed to packages/source-control by this PR; the
semantic-pull-requests.yml scope allowlist did not know the new name,
which failed the title-validation check on this PR's own title.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MJQxEwqaaP4aMG4E7yeaky
greptile-apps[bot]
greptile-appsBot previously approved these changes Aug 13, 2026
Merge origin/main (PR #29, "add bounded issue-to-PR workflows") into
this branch. #29 landed after this branch forked and built a new
GitHub-issue-to-PR feature directly on the old packages/github APIs —
the exact package this branch renamed to packages/source-control and
restructured into provider-neutral adapters, so a textual merge alone
could not reconcile the two.
Resolution: ported comments.ts, issues.ts, and pulls.ts into
packages/source-control/src/providers/github-{comments,issues,pulls}.ts
unchanged in behavior, re-exported from the package's public surface,
and rewired apps/server/src/router.ts so ingestWebhook dispatches
GitHub `issues` events to the ported pipeline ahead of the
provider-neutral review-event path (issue-to-PR remains GitHub-only;
it has no equivalent on the other providers yet). WebhookRequest keeps
its provider-neutral `{ body, headers }` shape; the issue workflow
reads its delivery id from `X-GitHub-Delivery` via the newly exported
`readHeader` helper instead of a GitHub-specific request field.
WebhookOutcome now carries two `accepted` variants (review vs. issue),
distinguished structurally as `'changeRequest' in outcome` /
`'issue' in outcome`, matching the pattern main's own tests already
used for `'pullRequest' in outcome`.
Also updated: apps/server/server/routes/webhooks/github.post.ts to
build a headers-record request and pass `providers: [...]` instead of
a bare secret; SKILL.md, docs/architecture.md, and README's remaining
`packages/github` mentions; router.test.ts's issue-webhook suite
rebuilt against the header-based request shape.
Verification: 161 packages/source-control tests, 97 apps/server tests,
and the full suite for agent/config/models/runner/shared/cli/auth
(188 tests) pass; typecheck and oxlint type-aware lint are clean for
every touched package; oxfmt is clean repo-wide; check:repo passes.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MJQxEwqaaP4aMG4E7yeaky
greptile-apps[bot]
greptile-appsBot previously approved these changes Aug 13, 2026
@RedStar071RedStar071 changed the title feat(source-control): add multi-provider source-control supportfeat: add multi-provider source-control supportAug 13, 2026
Merges main's mailing, i18n, and organizations work (PR #28) into the
source-control branch. No overlap with the provider-neutral adapters or
apps/server routing; pnpm-lock.yaml is reconciled by hand (aube is
unavailable in this environment) using the same packages/source-control
rename applied to the previous merge.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MJQxEwqaaP4aMG4E7yeaky
@socket-security

socket-securityBot commented Aug 13, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

DiffPackageSupply Chain
Security
VulnerabilityQualityMaintenanceLicense
Added@​agent-zero/​source-control@​0.3.0N/AN/AN/AN/AN/A

View full report

@socket-security

socket-securityBot commented Aug 13, 2026

Copy link
Copy Markdown

All alerts resolved. Learn more about Socket for GitHub.

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report

greptile-apps[bot]
greptile-appsBot previously approved these changes Aug 13, 2026
A local install with those two manifests temporarily sidelined (to route
around a sandboxed network block on pkg.pr.new, unrelated to this PR)
pruned their importer blocks from pnpm-lock.yaml before the previous
commit. CI's frozen-lockfile install then silently skipped both
workspaces, so packages/i18n's own dependencies (@lunariajs/core,
vue-i18n-extract) were never linked and its typecheck failed with
"Cannot find module", cascading into the other CI jobs via Turborepo's
lockfile-derived task graph.
Restored both importer blocks verbatim from origin/main's lockfile,
keeping the packages/source-control rename applied on top.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MJQxEwqaaP4aMG4E7yeaky
@kodiakhq
kodiakhqBot merged commit 514acb9 into mainAug 13, 2026
16 checks passed
@kodiakhq
kodiakhqBot deleted the claude/issue-14-implementation-9n4972 branch August 13, 2026 23:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: v0.5 add multi-provider source control support

2 participants

@RedStar071@claude