AI Agents SDE Task Viewer
      • Context
      • Plan
      • Prd
  1. Home
  2. AgentSDE
  3. agent-core
  4. gh-548
  5. plan
  6. plan.md
plan.md(4.4 KB)· Apr 23, 2026· 2 min read
  • Summary
  • Files
  • Steps
  • Verification
  • Risks
  • Open Questions

Plan — BJ-8: BitbucketService (GitHub parity surface)#

Summary#

Create BitbucketService and BitbucketModule under src/bitbucket/, mirroring the public surface of GitHubService against the Bitbucket Cloud v2 API. Wire PLATFORM_AUTH_PROVIDER via factory and ship unit tests covering each public method.

Files#

PathActionPurpose
src/bitbucket/bitbucket.service.tscreateAll 18 public methods + private request/sleep helpers, base https://api.bitbucket.org/2.0.
src/bitbucket/bitbucket.module.tscreateNestJS module exporting BitbucketService + PLATFORM_AUTH_PROVIDER token, factory injects BitbucketOAuthAuthProvider (from #542).
src/bitbucket/bitbucket.service.spec.tscreateUnit tests with fetch spy + mocked PlatformAuthProvider (mirrors github.service.spec.ts).
src/bitbucket/index.tscreateBarrel re-export of module + service (mirrors src/github/index.ts).

Steps#

  1. Implement BitbucketService private request<T>() helper: Bearer token from authProvider.getToken(), JSON Accept, 429 retry honouring Retry-After, 401 → call getToken() once more then retry; throw typed Error otherwise.
  2. Implement comments — postComment (POST /repositories/{ws}/{repo}/pullrequests/{id}/comments with {content:{raw}}), editComment (PUT …/comments/{cid}), findCommentByPrefix (paginated GET over values[].content.raw).
  3. Implement PR ops — createPR (POST /repositories/{ws}/{repo}/pullrequests, return {number: id}), mergePR (POST …/{id}/merge with squash strategy), updatePRBranch (no native API → log warn + no-op), closePR (POST …/{id}/decline, swallow 404/already-closed), enableAutoMerge (throw NotImplementedException).
  4. Implement labels via PR title-prefix fallback — addLabel/removeLabel fetch the PR, mutate title to add/strip [label] prefix, PUT it back.
  5. Implement file ops — getFileContent (GET /repositories/{ws}/{repo}/src/{ref}/{path}, return {content, sha:commit}, 404→null), getPRFiles (GET …/{id}/diffstat, map new.path), createOrUpdateFile (POST /repositories/{ws}/{repo}/src multipart with branch + message).
  6. Implement branches — createBranch (POST /repositories/{ws}/{repo}/refs/branches with {name, target:{hash}}, on conflict delete+recreate), getDefaultBranchSha (GET /repositories/{ws}/{repo} → mainbranch.name then GET …/refs/branches/{name} → target.hash), deleteBranch (DELETE …/refs/branches/{name}, swallow 404).
  7. Implement status — getCheckStatus (GET /repositories/{ws}/{repo}/commit/{ref}/statuses → map state SUCCESSFUL→passing, INPROGRESS→pending, return {passing,noChecks}), getReviewStatus (GET …/pullrequests/{id} → participants[].approved any-true).
  8. Treat owner argument as Bitbucket workspace slug across all paths (single positional rename only — keep the GitHub signature for substitutability).
  9. Wire bitbucket.module.ts: imports:[ConfigModule], factory provider for PLATFORM_AUTH_PROVIDER returning new BitbucketOAuthAuthProvider(config) (file from #542 — if missing at implementation time, raise as blocker).
  10. Write bitbucket.service.spec.ts: one describe per method group, spy on globalThis.fetch, mock PlatformAuthProvider returning a static token, assert URL + method + body + auth header; cover 429-retry, 401-refresh, label title-prefix round-trip, enableAutoMerge throws.

Verification#

  • npm run lint and npm run test pass with zero warnings (per CLAUDE.md zero-warnings policy).
  • New spec covers every public method; coverage report shows src/bitbucket/bitbucket.service.ts ≥ existing github.service.ts line coverage.
  • Module compiles in isolation: Test.createTestingModule({ imports: [BitbucketModule] }) resolves both BitbucketService and PLATFORM_AUTH_PROVIDER.

Risks#

  • #542 not yet merged — BitbucketOAuthAuthProvider does not exist on rc/atlassian-integration today. Mitigation: depend on the import path declared in #542 (../atlassian/bitbucket-oauth-auth.provider); if absent at impl time, surface via BLOCKED.
  • Bitbucket API quirks (multipart src upload, state enum naming) may force per-method shape divergence from GitHub — accept and document inline rather than force exact symmetry.

Open Questions#

  • None blocking — assumptions noted in issue (enableAutoMerge throws, label title-prefix fallback, retry-once on 401) are accepted.
ContextPrd