Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 5 additions & 2 deletions src/api/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ import {
refreshInstallationHealthForInstallation,
} from "../github/backfill";
import { getRepositoryCollaboratorPermission } from "../github/app";
import type { GittensoryFooterEnv } from "../github/footer";
import { contributorRepoStatsFromGittensor, fetchGittensorContributorSnapshot } from "../gittensor/api";
import { fetchPublicContributorProfile, fetchPublicRepoStats } from "../github/public";
import {
Expand Down Expand Up @@ -1701,7 +1702,7 @@ export function createApp() {
if (repoForbidden) return repoForbidden;
const installationId = repo?.installationId ?? null;
const installation = installationId !== null ? await getInstallationHealth(c.env, installationId) : null;
const preview = buildCommandPreview(command, parsed.data, { repo, installation, pullRequest });
const preview = buildCommandPreview(command, parsed.data, { repo, installation, pullRequest, env: c.env });
await recordRouteProductUsage(c, {
surface: "control_panel",
eventName: "command_previewed",
Expand Down Expand Up @@ -2690,6 +2691,7 @@ export function createApp() {
issues,
pullRequests,
sample: parsed.data.sample ?? {},
env: c.env,
}),
);
});
Expand Down Expand Up @@ -4262,7 +4264,7 @@ type CommandPreviewDecision = {
function buildCommandPreview(
command: (typeof APP_COMMANDS)[number],
request: z.infer<typeof commandPreviewSchema>,
context: { repo: RepositoryRecord | null; installation: InstallationHealthRecord | null; pullRequest: PullRequestRecord | null },
context: { repo: RepositoryRecord | null; installation: InstallationHealthRecord | null; pullRequest: PullRequestRecord | null; env: GittensoryFooterEnv },
) {
const target = request.repoFullName ? `${request.repoFullName}${request.pullNumber ? `#${request.pullNumber}` : ""}` : "selected target";
const mentionCommandName = previewableMentionCommandName(command.id);
Expand Down Expand Up @@ -4380,6 +4382,7 @@ function buildCommandPreview(
confirmedMinerLogins: sample.minerStatus === "confirmed" ? [sample.authorLogin] : [],
})
: null,
env: context.env,
});

return {
Expand Down
6 changes: 4 additions & 2 deletions src/github/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
suggestCommand as suggestCommandFromCatalog,
type CommandSuggestCatalog,
} from "./command-suggest";
import { gittensoryFooter, GITTENSORY_SITE_URL } from "./footer";
import { gittensoryFooter, GITTENSORY_SITE_URL, type GittensoryFooterEnv } from "./footer";
import type { AgentRunBundle } from "../services/agent-orchestrator";
import type { GittensorContributorSnapshot, OfficialGittensorMinerDetection } from "../gittensor/api";
import type { AgentActionRecord, RepositoryCommandAuthorizationPolicy } from "../types";
Expand Down Expand Up @@ -362,6 +362,8 @@ export function buildPublicAgentCommandComment(args: {
officialMiner?: GittensorContributorSnapshot | null | undefined;
bundle?: AgentRunBundle | null | undefined;
maintainerDigest?: MaintainerQueueDigest | null | undefined;
/** Resolved by the caller from `env.PUBLIC_SITE_ORIGIN` -- see `gittensoryFooter` (#4613). */
env: GittensoryFooterEnv;
}): string {
const repoFullName = args.repo?.fullName ?? args.pullRequest?.repoFullName ?? "this repository";
// Action commands (e.g. gate-override) never reach this Q&A renderer — they are handled and short-circuited
Expand Down Expand Up @@ -407,7 +409,7 @@ export function buildPublicAgentCommandComment(args: {
...feedbackPromptSections(args.answerId),
"",
"---",
gittensoryFooter(),
gittensoryFooter(args.env),
].join("\n");
return sanitizePublicComment(body);
}
Expand Down
22 changes: 17 additions & 5 deletions src/github/footer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,17 @@
// scoreability out of public output). This footer uses ONLY "earn" — a factual, public invitation,
// not a payout guarantee or a private-score disclosure.

/** The Gittensory product site (marketing on-ramp / attribution target). */
/** The Gittensory product site (marketing on-ramp / attribution target) -- the DEFAULT only. A
* self-hoster with `PUBLIC_SITE_ORIGIN` set gets their own domain instead, both here and in
* `gittensoryFooter` below (#4613). */
export const GITTENSORY_SITE_URL = "https://gittensory.aethereal.dev";

/** Minimal env slice `gittensoryFooter` needs, narrowed from the full `Env` the same way this file's
* `maintainerControlPanelUrl` already narrows its own `env` param inline -- so every file that renders
* the footer only has to thread this one field down from wherever the real `Env` is in scope, not the
* whole worker binding type. */
export type GittensoryFooterEnv = { PUBLIC_SITE_ORIGIN?: string | undefined };

/** The maintainer control panel for a repo on the Gittensory site (`/app?view=maintainer&repo=…`). Used as the
* check-run `details_url` so the merge-box "Details" link lands on the repo's review panel instead of GitHub's
* generic check page, and as the in-comment control-panel link. Returns null only if URL construction throws. */
Expand Down Expand Up @@ -39,8 +47,12 @@ export function gittensorRepoEarnUrl(repoFullName: string): string {
* appears on EVERY reviewed PR (the link persists forever), so non-registered authors see the
* invite and anyone viewing a registered contributor's PR sees it too. The registered/non-registered
* distinction lives in the review BODY (full panel vs. minimal), not here.
* Uses only "earn" wording — never reward/payout/score (forbidden in public comments). */
export function gittensoryFooter(opts: { earnUrl?: string | undefined; customText?: string | undefined } = {}): string {
* Uses only "earn" wording — never reward/payout/score (forbidden in public comments).
* `env.PUBLIC_SITE_ORIGIN` (same resolution as `maintainerControlPanelUrl` above) lets a self-hoster's
* own domain replace `GITTENSORY_SITE_URL` in the "Checked by Gittensory" attribution link (#4613) --
* the Gittensor register link (`GITTENSOR_HOME_URL`) is a separate, shared network and is never rebranded. */
export function gittensoryFooter(env: GittensoryFooterEnv, opts: { earnUrl?: string | undefined; customText?: string | undefined } = {}): string {
const siteUrl = env.PUBLIC_SITE_ORIGIN ?? GITTENSORY_SITE_URL;
const earnUrl = opts.earnUrl ?? GITTENSOR_HOME_URL;
// Maintainer-customized footer (via `.gittensory.yml review.footer.text`): the maintainer's public-safe
// lead replaces the default CTA copy, but the Gittensor register link + Gittensory attribution are
Expand All @@ -49,12 +61,12 @@ export function gittensoryFooter(opts: { earnUrl?: string | undefined; customTex
return [
opts.customText,
"",
`[Gittensor](${GITTENSOR_HOME_URL}) lets GitHub contributors earn for the work they already do — [register to start earning →](${earnUrl}). Checked by [Gittensory](${GITTENSORY_SITE_URL}).`,
`[Gittensor](${GITTENSOR_HOME_URL}) lets GitHub contributors earn for the work they already do — [register to start earning →](${earnUrl}). Checked by [Gittensory](${siteUrl}).`,
].join("\n");
}
return [
`💰 **Earn for open-source contributions like this.** [Gittensor](${GITTENSOR_HOME_URL}) lets GitHub contributors earn for the work they already do — [register to start earning →](${earnUrl}).`,
"",
`Checked by [Gittensory](${GITTENSORY_SITE_URL}), a quiet PR intelligence layer for OSS maintainers.`,
`Checked by [Gittensory](${siteUrl}), a quiet PR intelligence layer for OSS maintainers.`,
].join("\n");
}
6 changes: 5 additions & 1 deletion src/github/repo-doc-pr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
// the skill from this run rather than blocking the AGENTS.md refresh it rode in with.
import { githubErrorStatus, withInstallationTokenRetry } from "./app";
import { githubRateLimitAdmissionKeyForInstallation, makeInstallationOctokit } from "./client";
import { GITTENSORY_SITE_URL } from "./footer";
import { getRepository } from "../db/repositories";
import { loadRepoFocusManifest } from "../signals/focus-manifest-loader";
import { extractRepoProfile } from "../review/repo-profile";
Expand Down Expand Up @@ -148,7 +149,10 @@ export async function openRepoDocPullRequest(env: Env, repoFullName: string, mod

const profile = await extractRepoProfile(env, repoFullName);
if (!profile.present) return { opened: false, reason: profile.reason };
const generatedSection = renderRepoDocContent(profile);
// #4613: a self-hoster's own domain (env.PUBLIC_SITE_ORIGIN) reaches the generated AGENTS.md's
// attribution link instead of gittensory.aethereal.dev -- same fallback `maintainerControlPanelUrl`/
// `gittensoryFooter` already use.
const generatedSection = renderRepoDocContent(profile, env.PUBLIC_SITE_ORIGIN ?? GITTENSORY_SITE_URL);
if (!generatedSection) return { opened: false, reason: "no content rendered from profile" };

if (mode !== "live") return { opened: false, reason: `repo-doc pull request not opened: action mode is "${mode}"` };
Expand Down
Loading