Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
eb3fc61
feat(source-control): integrate Forgejo and Gitea servers
maria-rcks Sep 12, 2026
0e543d5
fix(source-control): preserve Forgejo origins and legacy drafts
maria-rcks Sep 12, 2026
24d2423
fix(source-control): distinguish Forgejo server ports
maria-rcks Sep 12, 2026
be7d20e
fix(source-control): accept Forgejo links on custom hostnames
maria-rcks Sep 12, 2026
8f7a445
fix(source-control): preserve Forgejo ports in saved PR links
maria-rcks Sep 12, 2026
b58ff82
fix(source-control): resolve Forgejo SSH web authorities
maria-rcks Sep 12, 2026
b817350
fix(source-control): persist Forgejo review reactions and match mount…
maria-rcks Sep 12, 2026
e7b3990
chore: merge main into Forgejo integration
maria-rcks Sep 12, 2026
c72fc1c
fix(source-control): resolve Forgejo pull request view URLs
maria-rcks Sep 12, 2026
b58b4ba
test(source-control): provide Forgejo filesystem stub
maria-rcks Sep 12, 2026
582b511
fix(source-control): retain Forgejo host in viewer lookup
maria-rcks Sep 12, 2026
d603fcb
fix(ui): use Forgejo brand orange across clients
maria-rcks Sep 12, 2026
29b829c
fix(ui): use the official two-color Forgejo mark
maria-rcks Sep 12, 2026
8ca797b
feat(source-control): prefer fj with tea fallback for Forgejo
maria-rcks Sep 12, 2026
5ed4247
fix(source-control): complete fj registry test setup
maria-rcks Sep 12, 2026
5824d9e
fix(source-control): handle fj account and empty mutation responses
maria-rcks Sep 12, 2026
4055ffa
fix(source-control): match ported fj SSH aliases
maria-rcks Sep 12, 2026
6169f1d
fix(source-control): submit Forgejo reviews with valid requests
maria-rcks Sep 13, 2026
c2245ac
fix(source-control): preserve Forgejo host and pagination context
maria-rcks Sep 13, 2026
9d745cc
fix(source-control): bound Forgejo inline activity requests
maria-rcks Sep 13, 2026
65154e4
fix(source-control): resolve Forgejo aliases and host-only requests
maria-rcks Sep 13, 2026
48198dc
fix(source-control): preserve HTTP auth and use tea for mounted servers
maria-rcks Sep 13, 2026
d036c33
fix(source-control): discover Forgejo HTTP hosts across named remotes
maria-rcks Sep 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion apps/mobile/src/components/SourceControlIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { withUniwind } from "uniwind";

const ThemedSvg = withUniwind(Svg);

export type SourceControlIconKind = "github" | "gitlab" | "bitbucket" | "azure-devops";
export type SourceControlIconKind = "github" | "gitlab" | "forgejo" | "bitbucket" | "azure-devops";

export function SourceControlIcon(props: {
readonly kind: SourceControlIconKind;
Expand All @@ -14,6 +14,19 @@ export function SourceControlIcon(props: {
const size = props.size ?? 18;

switch (props.kind) {
case "forgejo":
return (
<ThemedSvg
width={size}
height={size}
viewBox="0 0 24 24"
color={props.color}
colorClassName={props.colorClassName}
fill="currentColor"
>
<Path d="M16.7773 0c1.6018 0 2.9004 1.2986 2.9004 2.9005s-1.2986 2.9004-2.9004 2.9004c-1.0854 0-2.0315-.596-2.5288-1.4787H12.91c-2.3322 0-4.2272 1.8718-4.2649 4.195l-.0007 2.1175a7.0759 7.0759 0 0 1 4.148-1.4205l.1176-.001 1.3385.0002c.4973-.8827 1.4434-1.4788 2.5288-1.4788 1.6018 0 2.9004 1.2986 2.9004 2.9005s-1.2986 2.9004-2.9004 2.9004c-1.0854 0-2.0315-.596-2.5288-1.4787H12.91c-2.3322 0-4.2272 1.8718-4.2649 4.195l-.0007 2.319c.8827.4973 1.4788 1.4434 1.4788 2.5287 0 1.602-1.2986 2.9005-2.9005 2.9005-1.6018 0-2.9004-1.2986-2.9004-2.9005 0-1.0853.596-2.0314 1.4788-2.5287l-.0002-9.9831c0-3.887 3.1195-7.0453 6.9915-7.108l.1176-.001h1.3385C14.7458.5962 15.692 0 16.7773 0ZM7.2227 19.9052c-.6596 0-1.1943.5347-1.1943 1.1943s.5347 1.1943 1.1943 1.1943 1.1944-.5347 1.1944-1.1943-.5348-1.1943-1.1944-1.1943Zm9.5546-10.4644c-.6596 0-1.1944.5347-1.1944 1.1943s.5348 1.1943 1.1944 1.1943c.6596 0 1.1943-.5347 1.1943-1.1943s-.5347-1.1943-1.1943-1.1943Zm0-7.7346c-.6596 0-1.1944.5347-1.1944 1.1943s.5348 1.1943 1.1944 1.1943c.6596 0 1.1943-.5347 1.1943-1.1943s-.5347-1.1943-1.1943-1.1943Z" />
</ThemedSvg>
);
case "github":
return (
<ThemedSvg
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export function AddProjectRepositoryRoute({
const title =
source === "github" ||
source === "gitlab" ||
source === "forgejo" ||
source === "bitbucket" ||
source === "azure-devops"
? addProjectRemoteSourceLabel(source)
Expand Down
1 change: 1 addition & 0 deletions apps/mobile/src/features/projects/AddProjectScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ function sourceFromParam(value: string | string[] | undefined): AddProjectRemote
source === "url" ||
source === "github" ||
source === "gitlab" ||
source === "forgejo" ||
source === "bitbucket" ||
source === "azure-devops"
) {
Expand Down
10 changes: 9 additions & 1 deletion apps/server/src/git/GitManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,15 @@ export const make = Effect.gen(function* () {
(yield* readConfigValueNullable(cwd, `remote.${preferredRemoteName}.url`)) ??
(yield* readConfigValueNullable(cwd, "remote.origin.url"));

return remoteUrl ? detectSourceControlProviderFromGitRemoteUrl(remoteUrl) : null;
const provider = remoteUrl ? detectSourceControlProviderFromGitRemoteUrl(remoteUrl) : null;
if (!remoteUrl || provider?.kind !== "unknown") return provider;
const handle = yield* sourceControlProviders
.resolveHandle({
cwd,
context: { provider, remoteName: preferredRemoteName, remoteUrl },
})
.pipe(Effect.orElseSucceed(() => null));
return handle?.context?.provider ?? provider;
});

const resolveRemoteRepositoryContext = Effect.fn("resolveRemoteRepositoryContext")(function* (
Expand Down
34 changes: 34 additions & 0 deletions apps/server/src/mcp/toolkits/pullRequests/handlers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,40 @@ describe("pull request toolkit handlers", () => {
}),
);

it.effect("links a numeric Forgejo reference with its remote's web origin and mount path", () =>
Effect.gen(function* () {
const harness = yield* makeHarness({
project: makeProject({
canonicalKey: "forge.example/git/owner/repo",
locator: {
source: "git-remote",
remoteName: "origin",
remoteUrl: "http://forge.example:3000/git/owner/repo.git",
},
provider: "forgejo",
displayName: "git/owner/repo",
}),
});
const result = yield* harness.call("link_pull_request", {
repository: "git/owner/repo",
number: 42,
});
expect(result).toEqual({
host: "forge.example",
repository: "git/owner/repo",
number: 42,
url: "http://forge.example:3000/git/owner/repo/pulls/42",
alreadyLinked: false,
});
const other = yield* harness.call("link_pull_request", {
host: "other.example",
repository: "owner/repo",
number: 42,
});
expect(other.url).toBe("https://other.example/owner/repo/pull/42");
}),
);

it.effect("rejects a target that names neither a URL nor repository and number", () =>
Effect.gen(function* () {
const harness = yield* makeHarness();
Expand Down
1 change: 1 addition & 0 deletions apps/server/src/mcp/toolkits/pullRequests/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ const resolveTarget = Effect.fn("PullRequestsToolkit.resolveTarget")(function* (
host,
repository,
input.number,
project?.repositoryIdentity?.locator.remoteUrl,
Comment thread
maria-rcks marked this conversation as resolved.
) ?? `https://${host}/${repository}/pull/${input.number}`;
return { host, repository, number: input.number, url } satisfies ResolvedTarget;
});
Expand Down
Loading
Loading