Skip to content

Refactor: migrate forge-cli.ts logic into community/forge adapters (follow-up to #1104) #1574

@Wirasm

Description

@Wirasm

Summary

PR #1104 lands forge-agnostic outbound CRUD (create PR / view issue / add review comment / merge / etc.) for Gitea and GitLab via a single 822-line .archon/scripts/forge-cli.ts script. That unblocks the feature, but it sits parallel to the existing packages/adapters/src/community/forge/{gitea,gitlab}/adapter.ts files which already handle inbound webhooks for the same forges.

This issue tracks the architectural cleanup: migrate the outbound forge logic from the script into the existing community adapters so we have one extension point per forge rather than two.

This is not a regression riskforge-cli.ts works and has tests. It's about consolidating the pattern before more forges (Bitbucket, Sourcehut, etc.) calcify the parallel structure.

Why this matters

direction.md (updated alongside this issue) commits to forge-agnostic support with the long-term home being community adapters. Today after #1104 lands we have:

Operation Today's home
Inbound webhooks (handleWebhook) packages/adapters/src/community/forge/{gitea,gitlab}/adapter.ts
sendMessage (post comment) Same adapter ✅
Outbound CRUD (create-pr, view-issue, etc.) .archon/scripts/forge-cli.ts ❌ — separate script

Adding a new forge today means: implement an adapter (inbound + sendMessage) AND extend forge-cli.ts (outbound) AND wire bundled commands. After this refactor: extend the existing adapter only.

Scope

Define the outbound interface

Either extend IPlatformAdapter (in @archon/core) with optional outbound methods, or sibling-it as IForgeOperations if IPlatformAdapter would get bloated. Methods (deriving from forge-cli.ts's commands):

  • createPullRequest({ title, body, base, head, draft }) → { number, url }
  • viewIssue({ owner, repo, number }) → IssueView
  • viewPullRequest({ owner, repo, number }) → PullRequestView
  • addReviewComment({ owner, repo, prNumber, body, ... })
  • mergePullRequest({ owner, repo, number, method })
  • getDiff({ owner, repo, prNumber }) → string
  • setLabels({ owner, repo, number, labels })
  • (full method list to be derived from forge-cli.ts's top-level case statements)

Implement on each adapter

  • packages/adapters/src/forge/github/adapter.ts — uses Octokit (already present for sendMessage).
  • packages/adapters/src/community/forge/gitea/adapter.ts — Gitea API client.
  • packages/adapters/src/community/forge/gitlab/adapter.ts — GitLab API client.

Each forge owns its API quirks (e.g., GitLab's draft-MR title prefix, Gitea's raw_diffs endpoint — both already noted in #1104's commit messages) inside its own adapter.

Re-wire bundled commands

.archon/commands/defaults/archon-create-pr.md, archon-finalize-pr.md, archon-investigate-issue.md, etc. (25 files in #1104) currently call into forge-cli.ts via bash. After this refactor, they call into the adapter abstraction — likely via a workflow variable like $forge.create_pr or a tiny shim.

Reduce forge-cli.ts

Should drop to ~0 lines. The shared interface code may move to packages/adapters/src/forge/types.ts.

Acceptance criteria

Why we're not blocking #1104 on this

@truck0321 has been waiting 8+ days for the direction call and the feature is clean and well-tested. Asking for the architectural refactor before merge would be 2-3 hours of additional work on top of an already-rebased branch. Pragmatic move: ship the feature, track the refactor here, and migrate when someone has time (could be the original contributor, could be a maintainer pass).

References

Scope

  • Package(s) likely involved: adapters (community/forge/{gitea,gitlab,github}), core (interface definition), workflows (bundled command edits), bundled defaults regeneration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priority - Address soon, next in queuearchitectureArchitectural changes and designarea: adaptersPlatform adapterseffort/mediumFew files, one domain or module, some coordination neededfeatureNew functionality (planned)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions