Connect GitHub from a token alone (#195)

* Connect GitHub from a token alone, without a vendor account

Integrations only reached GitHub through Composio or Pipedream, which a
self-hosted instance does not have. A built-in GitHub row now opens
GitHub's prefilled token form, and the pasted token connects GitHub's
own MCP server through the existing installed-connector path. Web and
mobile.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tgvrj34NMnaqvtgvruYQZZ

* Sync web catalogs for the GitHub connect strings

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tgvrj34NMnaqvtgvruYQZZ

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
cynarAI 2026-10-10 13:18:44 +02:00 committed by GitHub
parent 797906dde2
commit 3469165c92
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 504 additions and 35 deletions

View File

@ -114,6 +114,7 @@ import {
AttachmentValidationError, AttachmentValidationError,
containsSecret, containsSecret,
expandSkillReferencesInPrompt, expandSkillReferencesInPrompt,
GITHUB_MCP_SOURCE,
hasMixedOneShotSchedule, hasMixedOneShotSchedule,
isOneShotRoutineCrons, isOneShotRoutineCrons,
isProjectColor, isProjectColor,
@ -3321,6 +3322,10 @@ export function createRouter(deps: RouterDeps) {
source = "https://treg.to/mcp/"; source = "https://treg.to/mcp/";
config = { ...config, preset: "treg", auth: { type: "bearer" } }; config = { ...config, preset: "treg", auth: { type: "bearer" } };
} }
if (config.preset === "github") {
source = GITHUB_MCP_SOURCE;
config = { preset: "github", auth: { type: "bearer" } };
}
const verified = await verifyMcpInstall({ const verified = await verifyMcpInstall({
source, source,
config, config,

View File

@ -5,7 +5,10 @@ import {
CONNECTION_CATALOG_PAGE_SIZE, CONNECTION_CATALOG_PAGE_SIZE,
EMPTY_PLUGIN_CATALOG_MESSAGE, EMPTY_PLUGIN_CATALOG_MESSAGE,
filterConnectionCatalogItems, filterConnectionCatalogItems,
GITHUB_MCP_SOURCE,
GITHUB_TOKEN_URL,
humanizeToolName, humanizeToolName,
isGithubInstall,
} from "@rakazo/core"; } from "@rakazo/core";
import { useEffect, useMemo, useRef, useState } from "react"; import { useEffect, useMemo, useRef, useState } from "react";
import { import {
@ -84,6 +87,11 @@ export default function Integrations() {
const [query, setQuery] = useState(""); const [query, setQuery] = useState("");
const [visibleCount, setVisibleCount] = useState(CONNECTION_CATALOG_PAGE_SIZE); const [visibleCount, setVisibleCount] = useState(CONNECTION_CATALOG_PAGE_SIZE);
const [sources, setSources] = useState<CapabilityInstall[]>([]); const [sources, setSources] = useState<CapabilityInstall[]>([]);
const github = sources.find(isGithubInstall);
const customSources = sources.filter((source) => !isGithubInstall(source));
const [githubOpen, setGithubOpen] = useState(false);
const [githubToken, setGithubToken] = useState("");
const [githubError, setGithubError] = useState<string | null>(null);
const [sourceKind, setSourceKind] = useState<SourceKind | null>(null); const [sourceKind, setSourceKind] = useState<SourceKind | null>(null);
const [advancedOpen, setAdvancedOpen] = useState(false); const [advancedOpen, setAdvancedOpen] = useState(false);
const [name, setName] = useState(""); const [name, setName] = useState("");
@ -388,6 +396,27 @@ export default function Integrations() {
} }
} }
async function connectGithub() {
setPending("github");
setGithubError(null);
try {
await rpc("capabilities/install", {
kind: "mcp",
name: "GitHub",
source: GITHUB_MCP_SOURCE,
credential: githubToken.trim(),
config: { preset: "github" },
});
setGithubToken("");
setGithubOpen(false);
await refresh();
} catch (reason) {
setGithubError(reason instanceof Error ? reason.message : t("Could not connect GitHub"));
} finally {
setPending(null);
}
}
async function removeSource(source: CapabilityInstall) { async function removeSource(source: CapabilityInstall) {
setPending(source.id); setPending(source.id);
setSourceError(null); setSourceError(null);
@ -592,6 +621,63 @@ export default function Integrations() {
renderDetail(detailItem) renderDetail(detailItem)
) : ( ) : (
<> <>
<View testID="github-connect" style={styles.card}>
<View style={styles.detailTitleRow}>
<ConnectorLogo label="GitHub" styles={styles} />
<Text style={[styles.title, styles.grow]}>GitHub</Text>
{github ? (
<Pressable
accessibilityRole="button"
disabled={pending === github.id}
onPress={() => void removeSource(github)}
>
<Text style={styles.remove}>{t("Disconnect")}</Text>
</Pressable>
) : githubOpen ? null : (
<Pressable
accessibilityRole="button"
onPress={() => setGithubOpen(true)}
style={styles.smallButton}
>
<Text style={styles.buttonLabel}>{t("Connect")}</Text>
</Pressable>
)}
</View>
{!github && githubOpen ? (
<>
<Pressable
accessibilityRole="link"
onPress={() => void Linking.openURL(GITHUB_TOKEN_URL)}
style={styles.cardButton}
>
<Text style={styles.buttonLabel}>{t("Create token on GitHub")}</Text>
</Pressable>
<TextInput
value={githubToken}
onChangeText={setGithubToken}
accessibilityLabel={t("GitHub token")}
placeholder="ghp_…"
placeholderTextColor={native.tertiaryLabel}
autoCapitalize="none"
autoCorrect={false}
secureTextEntry
style={styles.input}
/>
<Pressable
accessibilityRole="button"
disabled={pending === "github" || !githubToken.trim()}
onPress={() => void connectGithub()}
style={styles.cardButton}
>
<Text style={styles.buttonLabel}>
{pending === "github" ? t("Connecting…") : t("Connect")}
</Text>
</Pressable>
</>
) : null}
{githubError ? <Text style={styles.error}>{githubError}</Text> : null}
</View>
{!catalogReady ? <ActivityIndicator color={native.fillPressed} /> : null} {!catalogReady ? <ActivityIndicator color={native.fillPressed} /> : null}
{catalogReady && catalog.length === 0 ? ( {catalogReady && catalog.length === 0 ? (
@ -782,10 +868,10 @@ export default function Integrations() {
) : null} ) : null}
<Text style={styles.section}>{t("Tool sources")}</Text> <Text style={styles.section}>{t("Tool sources")}</Text>
{sources.length === 0 ? ( {customSources.length === 0 ? (
<Text style={styles.secondary}>{t("No custom sources installed.")}</Text> <Text style={styles.secondary}>{t("No custom sources installed.")}</Text>
) : null} ) : null}
{sources.map((source) => ( {customSources.map((source) => (
<View key={source.id} style={styles.row}> <View key={source.id} style={styles.row}>
<View style={styles.grow}> <View style={styles.grow}>
<Text style={styles.title}>{source.name}</Text> <Text style={styles.title}>{source.name}</Text>

View File

@ -1,4 +1,8 @@
export const DE_MESSAGES: Record<string, string> = { export const DE_MESSAGES: Record<string, string> = {
"Connecting…": "Verbinde…",
"GitHub token": "GitHub-Token",
"Create token on GitHub": "Token bei GitHub erstellen",
"Could not connect GitHub": "GitHub konnte nicht verbunden werden",
"1 step": "1 Schritt", "1 step": "1 Schritt",
"1 tool": "1 Tool", "1 tool": "1 Tool",
"@{name}": "@{name}", "@{name}": "@{name}",

View File

@ -1,4 +1,8 @@
export const RU_MESSAGES: Record<string, string> = { export const RU_MESSAGES: Record<string, string> = {
"Connecting…": "Подключение…",
"GitHub token": "Токен GitHub",
"Create token on GitHub": "Создать токен на GitHub",
"Could not connect GitHub": "Не удалось подключить GitHub",
"Update your server to use AI data sharing in this mobile version.": "Update your server to use AI data sharing in this mobile version.":
"Обновите сервер, чтобы использовать обмен данными с ИИ в этой версии мобильного приложения.", "Обновите сервер, чтобы использовать обмен данными с ИИ в этой версии мобильного приложения.",
"Ask the server owner to configure this provider.": "Ask the server owner to configure this provider.":

View File

@ -1,4 +1,8 @@
export const ZH_MESSAGES: Record<string, string> = { export const ZH_MESSAGES: Record<string, string> = {
"Connecting…": "正在连接…",
"GitHub token": "GitHub 令牌",
"Create token on GitHub": "在 GitHub 上创建令牌",
"Could not connect GitHub": "无法连接 GitHub",
"Update your server to use AI data sharing in this mobile version.": "Update your server to use AI data sharing in this mobile version.":
"请更新服务器,以便在此移动版本中使用 AI 数据共享功能。", "请更新服务器,以便在此移动版本中使用 AI 数据共享功能。",
"Release computer": "释放电脑", "Release computer": "释放电脑",

View File

@ -0,0 +1,30 @@
import { expect, test } from "@playwright/test";
import { captureScreenshot, completeOnboarding, openUserSettings, signup } from "./helpers";
test("GitHub connects from a token alone and disconnects again", async ({ page }, testInfo) => {
const stamp = Date.now();
await signup(page, `github-connect-${stamp}@rakazo.test`, "password12", "GitHub Connect");
await completeOnboarding(page);
await openUserSettings(page, "integrations");
const github = page.getByTestId("github-connect");
await expect(github).toBeVisible();
await github.getByRole("button", { name: "Connect", exact: true }).click();
await expect(github.getByRole("link", { name: "Create token on GitHub" })).toHaveAttribute(
"href",
/^https:\/\/github\.com\/settings\/tokens\/new\?description=evOo&scopes=repo/,
);
const token = github.getByLabel("GitHub token");
await token.fill("fake-github-token-value");
await captureScreenshot(page, testInfo, "github-connect");
await token.press("Enter");
await expect(github.getByText("Connected", { exact: true })).toBeVisible({ timeout: 30_000 });
await expect(token).toBeHidden();
await captureScreenshot(page, testInfo, "github-connected");
await page.reload({ waitUntil: "domcontentloaded" });
await openUserSettings(page, "integrations");
await expect(github.getByText("Connected", { exact: true })).toBeVisible({ timeout: 30_000 });
await github.getByRole("button", { name: "Disconnect" }).click();
await expect(github.getByRole("button", { name: "Connect", exact: true })).toBeVisible();
});

View File

@ -151,7 +151,8 @@ test("takeover, routine, plugins, and export are reachable", async ({ page }, te
await expect(featured).toContainText( await expect(featured).toContainText(
/Gmail[\s\S]*Google Calendar[\s\S]*Google Drive[\s\S]*Slack[\s\S]*Notion/, /Gmail[\s\S]*Google Calendar[\s\S]*Google Drive[\s\S]*Slack[\s\S]*Notion/,
); );
await expect(page.getByText("GitHub", { exact: true })).toBeVisible(); // The catalog tile and the built-in token connection.
await expect(page.getByText("GitHub", { exact: true })).toHaveCount(2);
await expect(page.getByRole("button", { name: "Add Executor", exact: true })).toBeHidden(); await expect(page.getByRole("button", { name: "Add Executor", exact: true })).toBeHidden();
await expect(page.getByRole("button", { name: "Add Treg", exact: true })).toBeHidden(); await expect(page.getByRole("button", { name: "Add Treg", exact: true })).toBeHidden();
await expect(page.getByRole("button", { name: "Add MCP server", exact: true })).toBeHidden(); await expect(page.getByRole("button", { name: "Add MCP server", exact: true })).toBeHidden();

View File

@ -0,0 +1,130 @@
import { Trans, useLingui } from "@lingui/react/macro";
import type { CapabilityInstall } from "@rakazo/contracts";
import { GITHUB_MCP_SOURCE, GITHUB_TOKEN_URL, isGithubInstall } from "@rakazo/core";
import { Button, buttonVariants, cn, Input } from "@rakazo/ui-web";
import { useState } from "react";
import { rpc } from "../../lib/rpc";
/** GitHub's mark, monochrome like the rest of the app. */
function GithubMark({ className }: { className?: string }) {
return (
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" className={className}>
<path d="M12 .3a12 12 0 0 0-3.8 23.4c.6.1.8-.3.8-.6v-2.2c-3.3.7-4-1.4-4-1.4-.6-1.4-1.4-1.8-1.4-1.8-1-.7.1-.7.1-.7 1.2.1 1.8 1.2 1.8 1.2 1 1.8 2.8 1.3 3.5 1 0-.8.4-1.3.7-1.6-2.7-.3-5.5-1.3-5.5-6 0-1.2.5-2.3 1.3-3.1-.2-.4-.6-1.6 0-3.2 0 0 1-.3 3.4 1.2a11.5 11.5 0 0 1 6 0c2.3-1.5 3.3-1.2 3.3-1.2.6 1.6.2 2.8.1 3.2.8.8 1.2 1.9 1.2 3.1 0 4.6-2.8 5.6-5.5 5.9.5.4.9 1.1.9 2.2v3.3c0 .3.1.7.8.6A12 12 0 0 0 12 .3" />
</svg>
);
}
/**
* GitHub without a vendor account or an app registration: a token from GitHub's prefilled form
* connects GitHub's own MCP server for every bot.
*/
export function GithubConnect({
sources,
onChanged,
}: {
sources: CapabilityInstall[];
onChanged: () => Promise<unknown>;
}) {
const { t } = useLingui();
const installed = sources.find(isGithubInstall);
const [open, setOpen] = useState(false);
const [token, setToken] = useState("");
const [pending, setPending] = useState(false);
const [error, setError] = useState<string | null>(null);
async function run(task: () => Promise<unknown>) {
setPending(true);
setError(null);
try {
await task();
await onChanged();
} catch (err) {
setError(err instanceof Error ? err.message : t`Could not connect GitHub`);
} finally {
setPending(false);
}
}
return (
<div data-testid="github-connect" className="mb-6 rounded-xl border border-border px-3 py-2.5">
<div className="flex items-center gap-3">
<div className="grid size-9 shrink-0 place-items-center rounded-xl bg-accent text-foreground">
<GithubMark className="size-5" />
</div>
<div className="min-w-0 flex-1 truncate text-ui-body font-medium text-foreground">
GitHub
</div>
{installed ? (
<>
<span className="text-ui-body-sm text-muted-foreground">
<Trans>Connected</Trans>
</span>
<Button
type="button"
variant="ghost"
size="sm"
className="rounded-full"
disabled={pending}
onClick={() => void run(() => rpc.capabilities.remove({ id: installed.id }))}
>
<Trans>Disconnect</Trans>
</Button>
</>
) : open ? null : (
<Button
type="button"
variant="secondary"
size="sm"
className="rounded-full"
onClick={() => setOpen(true)}
>
<Trans>Connect</Trans>
</Button>
)}
</div>
{!installed && open ? (
<form
className="mt-3 flex flex-col gap-2"
onSubmit={(event) => {
event.preventDefault();
void run(async () => {
await rpc.capabilities.install({
kind: "mcp",
name: "GitHub",
source: GITHUB_MCP_SOURCE,
credential: token.trim(),
config: { preset: "github" },
});
setToken("");
setOpen(false);
});
}}
>
<a
href={GITHUB_TOKEN_URL}
target="_blank"
rel="noreferrer"
className={cn(buttonVariants({ variant: "outline" }), "rounded-full")}
>
<Trans>Create token on GitHub</Trans>
</a>
<div className="flex gap-2">
<Input
type="password"
autoComplete="off"
value={token}
onChange={(event) => setToken(event.target.value)}
aria-label={t`GitHub token`}
placeholder="ghp_…"
className="h-10 flex-1 rounded-full px-4"
/>
<Button type="submit" className="rounded-full" disabled={pending || !token.trim()}>
{pending ? <Trans>Connecting…</Trans> : <Trans>Connect</Trans>}
</Button>
</div>
</form>
) : null}
{error ? <p className="mt-2 text-ui-body-sm text-destructive">{error}</p> : null}
</div>
);
}

View File

@ -1462,6 +1462,7 @@ msgstr "Löschen bestätigen"
msgid "Confirm password" msgid "Confirm password"
msgstr "Passwort bestätigen" msgstr "Passwort bestätigen"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
#: src/pages/memory-providers/SerenitySettingsForm.tsx #: src/pages/memory-providers/SerenitySettingsForm.tsx
@ -1506,6 +1507,7 @@ msgstr "Verbinde Tools, wenn du bereit bist"
msgid "Connect Treg" msgid "Connect Treg"
msgstr "Treg verbinden" msgstr "Treg verbinden"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpOAuthCallback.tsx #: src/pages/McpOAuthCallback.tsx
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
@ -1537,6 +1539,7 @@ msgstr "Verbunden. Die Tools sind ab deiner nächsten Nachricht verfügbar."
msgid "Connecting you with {target}." msgid "Connecting you with {target}."
msgstr "Ich verbinde dich mit {target}." msgstr "Ich verbinde dich mit {target}."
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
@ -1642,6 +1645,10 @@ msgstr "Verbindung fehlgeschlagen"
msgid "Could not connect {0}" msgid "Could not connect {0}"
msgstr "Verbindung mit {0} fehlgeschlagen" msgstr "Verbindung mit {0} fehlgeschlagen"
#: src/components/integrations/GithubConnect.tsx
msgid "Could not connect GitHub"
msgstr "GitHub konnte nicht verbunden werden"
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
msgid "Could not connect this provider" msgid "Could not connect this provider"
msgstr "Anbieter konnte nicht verbunden werden" msgstr "Anbieter konnte nicht verbunden werden"
@ -2010,6 +2017,10 @@ msgstr "Projekt erstellen"
msgid "Create space" msgid "Create space"
msgstr "Space erstellen" msgstr "Space erstellen"
#: src/components/integrations/GithubConnect.tsx
msgid "Create token on GitHub"
msgstr "Token bei GitHub erstellen"
#: src/pages/Auth.tsx #: src/pages/Auth.tsx
msgid "Create your evOo" msgid "Create your evOo"
msgstr "Dein evOo erstellen" msgstr "Dein evOo erstellen"
@ -2217,6 +2228,7 @@ msgstr "Diktat fehlgeschlagen."
msgid "Direct MCP" msgid "Direct MCP"
msgstr "Direktes MCP" msgstr "Direktes MCP"
#: src/components/integrations/GithubConnect.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/MemorySettingsOverlay.tsx #: src/pages/MemorySettingsOverlay.tsx
msgid "Disconnect" msgid "Disconnect"
@ -2694,6 +2706,10 @@ msgstr "Geist"
msgid "Git event" msgid "Git event"
msgstr "Git-Ereignis" msgstr "Git-Ereignis"
#: src/components/integrations/GithubConnect.tsx
msgid "GitHub token"
msgstr "GitHub-Token"
#: src/components/OoAtelier.tsx #: src/components/OoAtelier.tsx
msgid "Glass" msgid "Glass"
msgstr "Glas" msgstr "Glas"

View File

@ -1462,6 +1462,7 @@ msgstr "Confirm delete"
msgid "Confirm password" msgid "Confirm password"
msgstr "Confirm password" msgstr "Confirm password"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
#: src/pages/memory-providers/SerenitySettingsForm.tsx #: src/pages/memory-providers/SerenitySettingsForm.tsx
@ -1506,6 +1507,7 @@ msgstr "Connect tools when you''re ready"
msgid "Connect Treg" msgid "Connect Treg"
msgstr "Connect Treg" msgstr "Connect Treg"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpOAuthCallback.tsx #: src/pages/McpOAuthCallback.tsx
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
@ -1537,6 +1539,7 @@ msgstr "Connected. Its tools are available from your next message."
msgid "Connecting you with {target}." msgid "Connecting you with {target}."
msgstr "Connecting you with {target}." msgstr "Connecting you with {target}."
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
@ -1642,6 +1645,10 @@ msgstr "Could not connect"
msgid "Could not connect {0}" msgid "Could not connect {0}"
msgstr "Could not connect {0}" msgstr "Could not connect {0}"
#: src/components/integrations/GithubConnect.tsx
msgid "Could not connect GitHub"
msgstr "Could not connect GitHub"
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
msgid "Could not connect this provider" msgid "Could not connect this provider"
msgstr "Could not connect this provider" msgstr "Could not connect this provider"
@ -2010,6 +2017,10 @@ msgstr "Create project"
msgid "Create space" msgid "Create space"
msgstr "Create space" msgstr "Create space"
#: src/components/integrations/GithubConnect.tsx
msgid "Create token on GitHub"
msgstr "Create token on GitHub"
#: src/pages/Auth.tsx #: src/pages/Auth.tsx
msgid "Create your evOo" msgid "Create your evOo"
msgstr "Create your evOo" msgstr "Create your evOo"
@ -2217,6 +2228,7 @@ msgstr "Dictation failed."
msgid "Direct MCP" msgid "Direct MCP"
msgstr "Direct MCP" msgstr "Direct MCP"
#: src/components/integrations/GithubConnect.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/MemorySettingsOverlay.tsx #: src/pages/MemorySettingsOverlay.tsx
msgid "Disconnect" msgid "Disconnect"
@ -2694,6 +2706,10 @@ msgstr "Ghost"
msgid "Git event" msgid "Git event"
msgstr "Git event" msgstr "Git event"
#: src/components/integrations/GithubConnect.tsx
msgid "GitHub token"
msgstr "GitHub token"
#: src/components/OoAtelier.tsx #: src/components/OoAtelier.tsx
msgid "Glass" msgid "Glass"
msgstr "Glass" msgstr "Glass"

View File

@ -1462,6 +1462,7 @@ msgstr "Confirmar eliminación"
msgid "Confirm password" msgid "Confirm password"
msgstr "Confirmar contraseña" msgstr "Confirmar contraseña"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
#: src/pages/memory-providers/SerenitySettingsForm.tsx #: src/pages/memory-providers/SerenitySettingsForm.tsx
@ -1506,6 +1507,7 @@ msgstr ""
msgid "Connect Treg" msgid "Connect Treg"
msgstr "Conectar Treg" msgstr "Conectar Treg"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpOAuthCallback.tsx #: src/pages/McpOAuthCallback.tsx
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
@ -1537,6 +1539,7 @@ msgstr "Conectado: sus herramientas estarán disponibles desde tu próximo mensa
msgid "Connecting you with {target}." msgid "Connecting you with {target}."
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
@ -1642,6 +1645,10 @@ msgstr "No se pudo conectar"
msgid "Could not connect {0}" msgid "Could not connect {0}"
msgstr "No se pudo conectar {0}" msgstr "No se pudo conectar {0}"
#: src/components/integrations/GithubConnect.tsx
msgid "Could not connect GitHub"
msgstr ""
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
msgid "Could not connect this provider" msgid "Could not connect this provider"
msgstr "No se pudo conectar este proveedor" msgstr "No se pudo conectar este proveedor"
@ -2010,6 +2017,10 @@ msgstr ""
msgid "Create space" msgid "Create space"
msgstr "Crear space" msgstr "Crear space"
#: src/components/integrations/GithubConnect.tsx
msgid "Create token on GitHub"
msgstr ""
#: src/pages/Auth.tsx #: src/pages/Auth.tsx
msgid "Create your evOo" msgid "Create your evOo"
msgstr "" msgstr ""
@ -2217,6 +2228,7 @@ msgstr ""
msgid "Direct MCP" msgid "Direct MCP"
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/MemorySettingsOverlay.tsx #: src/pages/MemorySettingsOverlay.tsx
msgid "Disconnect" msgid "Disconnect"
@ -2694,6 +2706,10 @@ msgstr ""
msgid "Git event" msgid "Git event"
msgstr "Evento de Git" msgstr "Evento de Git"
#: src/components/integrations/GithubConnect.tsx
msgid "GitHub token"
msgstr ""
#: src/components/OoAtelier.tsx #: src/components/OoAtelier.tsx
msgid "Glass" msgid "Glass"
msgstr "" msgstr ""

View File

@ -1462,6 +1462,7 @@ msgstr "डिलीट की पुष्टि करें"
msgid "Confirm password" msgid "Confirm password"
msgstr "पासवर्ड की पुष्टि करें" msgstr "पासवर्ड की पुष्टि करें"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
#: src/pages/memory-providers/SerenitySettingsForm.tsx #: src/pages/memory-providers/SerenitySettingsForm.tsx
@ -1506,6 +1507,7 @@ msgstr ""
msgid "Connect Treg" msgid "Connect Treg"
msgstr "Treg कनेक्ट करें" msgstr "Treg कनेक्ट करें"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpOAuthCallback.tsx #: src/pages/McpOAuthCallback.tsx
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
@ -1537,6 +1539,7 @@ msgstr "कनेक्टेड। इसके टूल आपके अग
msgid "Connecting you with {target}." msgid "Connecting you with {target}."
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
@ -1642,6 +1645,10 @@ msgstr "कनेक्ट नहीं हो सका"
msgid "Could not connect {0}" msgid "Could not connect {0}"
msgstr "{0} कनेक्ट नहीं हो सका" msgstr "{0} कनेक्ट नहीं हो सका"
#: src/components/integrations/GithubConnect.tsx
msgid "Could not connect GitHub"
msgstr ""
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
msgid "Could not connect this provider" msgid "Could not connect this provider"
msgstr "यह प्रोवाइडर कनेक्ट नहीं हो सका" msgstr "यह प्रोवाइडर कनेक्ट नहीं हो सका"
@ -2010,6 +2017,10 @@ msgstr ""
msgid "Create space" msgid "Create space"
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
msgid "Create token on GitHub"
msgstr ""
#: src/pages/Auth.tsx #: src/pages/Auth.tsx
msgid "Create your evOo" msgid "Create your evOo"
msgstr "" msgstr ""
@ -2217,6 +2228,7 @@ msgstr ""
msgid "Direct MCP" msgid "Direct MCP"
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/MemorySettingsOverlay.tsx #: src/pages/MemorySettingsOverlay.tsx
msgid "Disconnect" msgid "Disconnect"
@ -2694,6 +2706,10 @@ msgstr ""
msgid "Git event" msgid "Git event"
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
msgid "GitHub token"
msgstr ""
#: src/components/OoAtelier.tsx #: src/components/OoAtelier.tsx
msgid "Glass" msgid "Glass"
msgstr "" msgstr ""

View File

@ -1462,6 +1462,7 @@ msgstr "삭제 확인"
msgid "Confirm password" msgid "Confirm password"
msgstr "비밀번호 확인" msgstr "비밀번호 확인"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
#: src/pages/memory-providers/SerenitySettingsForm.tsx #: src/pages/memory-providers/SerenitySettingsForm.tsx
@ -1506,6 +1507,7 @@ msgstr ""
msgid "Connect Treg" msgid "Connect Treg"
msgstr "Treg 연결" msgstr "Treg 연결"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpOAuthCallback.tsx #: src/pages/McpOAuthCallback.tsx
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
@ -1537,6 +1539,7 @@ msgstr "연결되었습니다. 다음 메시지부터 이 도구를 사용할
msgid "Connecting you with {target}." msgid "Connecting you with {target}."
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
@ -1642,6 +1645,10 @@ msgstr "연결하지 못했습니다."
msgid "Could not connect {0}" msgid "Could not connect {0}"
msgstr "{0}에 연결하지 못했습니다." msgstr "{0}에 연결하지 못했습니다."
#: src/components/integrations/GithubConnect.tsx
msgid "Could not connect GitHub"
msgstr ""
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
msgid "Could not connect this provider" msgid "Could not connect this provider"
msgstr "AI 서비스에 연결하지 못했습니다." msgstr "AI 서비스에 연결하지 못했습니다."
@ -2010,6 +2017,10 @@ msgstr ""
msgid "Create space" msgid "Create space"
msgstr "스페이스 만들기" msgstr "스페이스 만들기"
#: src/components/integrations/GithubConnect.tsx
msgid "Create token on GitHub"
msgstr ""
#: src/pages/Auth.tsx #: src/pages/Auth.tsx
msgid "Create your evOo" msgid "Create your evOo"
msgstr "" msgstr ""
@ -2217,6 +2228,7 @@ msgstr ""
msgid "Direct MCP" msgid "Direct MCP"
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/MemorySettingsOverlay.tsx #: src/pages/MemorySettingsOverlay.tsx
msgid "Disconnect" msgid "Disconnect"
@ -2694,6 +2706,10 @@ msgstr ""
msgid "Git event" msgid "Git event"
msgstr "Git 이벤트" msgstr "Git 이벤트"
#: src/components/integrations/GithubConnect.tsx
msgid "GitHub token"
msgstr ""
#: src/components/OoAtelier.tsx #: src/components/OoAtelier.tsx
msgid "Glass" msgid "Glass"
msgstr "" msgstr ""

View File

@ -1462,6 +1462,7 @@ msgstr "Confirmar exclusão"
msgid "Confirm password" msgid "Confirm password"
msgstr "Confirmar senha" msgstr "Confirmar senha"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
#: src/pages/memory-providers/SerenitySettingsForm.tsx #: src/pages/memory-providers/SerenitySettingsForm.tsx
@ -1506,6 +1507,7 @@ msgstr ""
msgid "Connect Treg" msgid "Connect Treg"
msgstr "Conectar Treg" msgstr "Conectar Treg"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpOAuthCallback.tsx #: src/pages/McpOAuthCallback.tsx
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
@ -1537,6 +1539,7 @@ msgstr "Conectado. Suas ferramentas estão disponíveis na sua próxima mensagem
msgid "Connecting you with {target}." msgid "Connecting you with {target}."
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
@ -1642,6 +1645,10 @@ msgstr "Não foi possível conectar"
msgid "Could not connect {0}" msgid "Could not connect {0}"
msgstr "Não foi possível conectar o {0}" msgstr "Não foi possível conectar o {0}"
#: src/components/integrations/GithubConnect.tsx
msgid "Could not connect GitHub"
msgstr ""
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
msgid "Could not connect this provider" msgid "Could not connect this provider"
msgstr "Não foi possível conectar este provedor" msgstr "Não foi possível conectar este provedor"
@ -2010,6 +2017,10 @@ msgstr ""
msgid "Create space" msgid "Create space"
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
msgid "Create token on GitHub"
msgstr ""
#: src/pages/Auth.tsx #: src/pages/Auth.tsx
msgid "Create your evOo" msgid "Create your evOo"
msgstr "" msgstr ""
@ -2217,6 +2228,7 @@ msgstr ""
msgid "Direct MCP" msgid "Direct MCP"
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/MemorySettingsOverlay.tsx #: src/pages/MemorySettingsOverlay.tsx
msgid "Disconnect" msgid "Disconnect"
@ -2694,6 +2706,10 @@ msgstr ""
msgid "Git event" msgid "Git event"
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
msgid "GitHub token"
msgstr ""
#: src/components/OoAtelier.tsx #: src/components/OoAtelier.tsx
msgid "Glass" msgid "Glass"
msgstr "" msgstr ""

View File

@ -1462,6 +1462,7 @@ msgstr "Подтвердить удаление"
msgid "Confirm password" msgid "Confirm password"
msgstr "Подтвердите пароль" msgstr "Подтвердите пароль"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
#: src/pages/memory-providers/SerenitySettingsForm.tsx #: src/pages/memory-providers/SerenitySettingsForm.tsx
@ -1506,6 +1507,7 @@ msgstr ""
msgid "Connect Treg" msgid "Connect Treg"
msgstr "Подключить Treg" msgstr "Подключить Treg"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpOAuthCallback.tsx #: src/pages/McpOAuthCallback.tsx
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
@ -1537,6 +1539,7 @@ msgstr "Подключено. Его инструменты доступны и
msgid "Connecting you with {target}." msgid "Connecting you with {target}."
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
@ -1642,6 +1645,10 @@ msgstr "Не удалось подключиться"
msgid "Could not connect {0}" msgid "Could not connect {0}"
msgstr "Не удалось подключить {0}" msgstr "Не удалось подключить {0}"
#: src/components/integrations/GithubConnect.tsx
msgid "Could not connect GitHub"
msgstr ""
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
msgid "Could not connect this provider" msgid "Could not connect this provider"
msgstr "Не удалось подключить этого провайдера" msgstr "Не удалось подключить этого провайдера"
@ -2010,6 +2017,10 @@ msgstr ""
msgid "Create space" msgid "Create space"
msgstr "Создайте пространство" msgstr "Создайте пространство"
#: src/components/integrations/GithubConnect.tsx
msgid "Create token on GitHub"
msgstr ""
#: src/pages/Auth.tsx #: src/pages/Auth.tsx
msgid "Create your evOo" msgid "Create your evOo"
msgstr "" msgstr ""
@ -2217,6 +2228,7 @@ msgstr ""
msgid "Direct MCP" msgid "Direct MCP"
msgstr "Прямой MCP" msgstr "Прямой MCP"
#: src/components/integrations/GithubConnect.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/MemorySettingsOverlay.tsx #: src/pages/MemorySettingsOverlay.tsx
msgid "Disconnect" msgid "Disconnect"
@ -2694,6 +2706,10 @@ msgstr ""
msgid "Git event" msgid "Git event"
msgstr "Git-событие" msgstr "Git-событие"
#: src/components/integrations/GithubConnect.tsx
msgid "GitHub token"
msgstr ""
#: src/components/OoAtelier.tsx #: src/components/OoAtelier.tsx
msgid "Glass" msgid "Glass"
msgstr "" msgstr ""

View File

@ -1462,6 +1462,7 @@ msgstr "Silmeyi onayla"
msgid "Confirm password" msgid "Confirm password"
msgstr "Parolayı doğrulayın" msgstr "Parolayı doğrulayın"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
#: src/pages/memory-providers/SerenitySettingsForm.tsx #: src/pages/memory-providers/SerenitySettingsForm.tsx
@ -1506,6 +1507,7 @@ msgstr ""
msgid "Connect Treg" msgid "Connect Treg"
msgstr "Treg'i bağla" msgstr "Treg'i bağla"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpOAuthCallback.tsx #: src/pages/McpOAuthCallback.tsx
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
@ -1537,6 +1539,7 @@ msgstr "Bağlandı. Araçları bir sonraki mesajından itibaren kullanılabilir.
msgid "Connecting you with {target}." msgid "Connecting you with {target}."
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
@ -1642,6 +1645,10 @@ msgstr "Bağlanılamadı"
msgid "Could not connect {0}" msgid "Could not connect {0}"
msgstr "{0} bağlanamadı" msgstr "{0} bağlanamadı"
#: src/components/integrations/GithubConnect.tsx
msgid "Could not connect GitHub"
msgstr ""
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
msgid "Could not connect this provider" msgid "Could not connect this provider"
msgstr "Bu sağlayıcı bağlanamadı" msgstr "Bu sağlayıcı bağlanamadı"
@ -2010,6 +2017,10 @@ msgstr ""
msgid "Create space" msgid "Create space"
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
msgid "Create token on GitHub"
msgstr ""
#: src/pages/Auth.tsx #: src/pages/Auth.tsx
msgid "Create your evOo" msgid "Create your evOo"
msgstr "" msgstr ""
@ -2217,6 +2228,7 @@ msgstr ""
msgid "Direct MCP" msgid "Direct MCP"
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/MemorySettingsOverlay.tsx #: src/pages/MemorySettingsOverlay.tsx
msgid "Disconnect" msgid "Disconnect"
@ -2694,6 +2706,10 @@ msgstr ""
msgid "Git event" msgid "Git event"
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
msgid "GitHub token"
msgstr ""
#: src/components/OoAtelier.tsx #: src/components/OoAtelier.tsx
msgid "Glass" msgid "Glass"
msgstr "" msgstr ""

View File

@ -1462,6 +1462,7 @@ msgstr "确认删除"
msgid "Confirm password" msgid "Confirm password"
msgstr "确认密码" msgstr "确认密码"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
#: src/pages/memory-providers/SerenitySettingsForm.tsx #: src/pages/memory-providers/SerenitySettingsForm.tsx
@ -1506,6 +1507,7 @@ msgstr ""
msgid "Connect Treg" msgid "Connect Treg"
msgstr "连接 Treg" msgstr "连接 Treg"
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpOAuthCallback.tsx #: src/pages/McpOAuthCallback.tsx
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
@ -1537,6 +1539,7 @@ msgstr "已连接,下一条消息起即可使用其工具。"
msgid "Connecting you with {target}." msgid "Connecting you with {target}."
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
#: src/components/integrations/IntegrationSetup.tsx #: src/components/integrations/IntegrationSetup.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/memory-providers/BuiltinSettingsForm.tsx #: src/pages/memory-providers/BuiltinSettingsForm.tsx
@ -1642,6 +1645,10 @@ msgstr "无法连接"
msgid "Could not connect {0}" msgid "Could not connect {0}"
msgstr "无法连接 {0}" msgstr "无法连接 {0}"
#: src/components/integrations/GithubConnect.tsx
msgid "Could not connect GitHub"
msgstr ""
#: src/pages/ModelSettingsOverlay.tsx #: src/pages/ModelSettingsOverlay.tsx
msgid "Could not connect this provider" msgid "Could not connect this provider"
msgstr "无法连接此提供方" msgstr "无法连接此提供方"
@ -2010,6 +2017,10 @@ msgstr ""
msgid "Create space" msgid "Create space"
msgstr "创建工作区" msgstr "创建工作区"
#: src/components/integrations/GithubConnect.tsx
msgid "Create token on GitHub"
msgstr ""
#: src/pages/Auth.tsx #: src/pages/Auth.tsx
msgid "Create your evOo" msgid "Create your evOo"
msgstr "" msgstr ""
@ -2217,6 +2228,7 @@ msgstr ""
msgid "Direct MCP" msgid "Direct MCP"
msgstr "" msgstr ""
#: src/components/integrations/GithubConnect.tsx
#: src/pages/McpServersOverlay.tsx #: src/pages/McpServersOverlay.tsx
#: src/pages/MemorySettingsOverlay.tsx #: src/pages/MemorySettingsOverlay.tsx
msgid "Disconnect" msgid "Disconnect"
@ -2694,6 +2706,10 @@ msgstr ""
msgid "Git event" msgid "Git event"
msgstr "Git 事件" msgstr "Git 事件"
#: src/components/integrations/GithubConnect.tsx
msgid "GitHub token"
msgstr ""
#: src/components/OoAtelier.tsx #: src/components/OoAtelier.tsx
msgid "Glass" msgid "Glass"
msgstr "" msgstr ""

View File

@ -13,6 +13,7 @@ import {
EMPTY_PLUGIN_CATALOG_MESSAGE, EMPTY_PLUGIN_CATALOG_MESSAGE,
filterConnectionCatalogItems, filterConnectionCatalogItems,
humanizeToolName, humanizeToolName,
isGithubInstall,
} from "@rakazo/core"; } from "@rakazo/core";
import { import {
Button, Button,
@ -31,6 +32,7 @@ import {
} from "@rakazo/ui-web"; } from "@rakazo/ui-web";
import { ChevronDown, ChevronLeft, ChevronUp, X } from "lucide-react"; import { ChevronDown, ChevronLeft, ChevronUp, X } from "lucide-react";
import { useEffect, useMemo, useRef, useState } from "react"; import { useEffect, useMemo, useRef, useState } from "react";
import { GithubConnect } from "../components/integrations/GithubConnect";
import { IntegrationSetup } from "../components/integrations/IntegrationSetup"; import { IntegrationSetup } from "../components/integrations/IntegrationSetup";
import { optionalCatalogFeedProbe } from "../lib/optional-catalog-feed"; import { optionalCatalogFeedProbe } from "../lib/optional-catalog-feed";
import { rpc } from "../lib/rpc"; import { rpc } from "../lib/rpc";
@ -717,6 +719,7 @@ export function PluginsOverlay({
renderDetail(detailItem) renderDetail(detailItem)
) : ( ) : (
<> <>
{!loading ? <GithubConnect sources={sources} onChanged={refresh} /> : null}
{loading ? ( {loading ? (
<p className="text-muted-foreground/80"> <p className="text-muted-foreground/80">
<Trans>Loading integrations…</Trans> <Trans>Loading integrations…</Trans>
@ -1096,41 +1099,46 @@ export function PluginsOverlay({
<div className="mb-3 text-sm font-medium text-foreground/75"> <div className="mb-3 text-sm font-medium text-foreground/75">
<Trans>Tool sources</Trans> <Trans>Tool sources</Trans>
</div> </div>
{sources.length === 0 && !sourceKind ? ( {sources.every(isGithubInstall) && !sourceKind ? (
<p className="text-muted-foreground/80"> <p className="text-muted-foreground/80">
<Trans>No MCP or API tool sources installed yet.</Trans> <Trans>No MCP or API tool sources installed yet.</Trans>
</p> </p>
) : null} ) : null}
{sources.map((source) => ( {sources
<div key={source.id} className="flex items-center gap-4 rounded-xl px-3 py-2.5"> .filter((source) => !isGithubInstall(source))
<div className="grid h-[42px] w-[42px] place-items-center rounded-xl bg-accent font-semibold uppercase text-foreground"> .map((source) => (
{source.kind === "mcp" ? "M" : source.kind === "graphql" ? "G" : "A"} <div
</div> key={source.id}
<div className="min-w-0 flex-1"> className="flex items-center gap-4 rounded-xl px-3 py-2.5"
<div className="text-ui-body font-medium text-foreground">
{source.name}
</div>
<div className="truncate text-ui-body text-muted-foreground/70">
{source.kind.toUpperCase()} · {source.source} ·{" "}
{source.secretConfigured ? (
<Trans>credential saved</Trans>
) : (
<Trans>no auth</Trans>
)}
</div>
</div>
<Button
type="button"
variant="secondary"
className="rounded-full"
size="sm"
disabled={pending === source.id}
onClick={() => void removeSource(source)}
> >
{pending === source.id ? <Trans>Removing…</Trans> : <Trans>Remove</Trans>} <div className="grid h-[42px] w-[42px] place-items-center rounded-xl bg-accent font-semibold uppercase text-foreground">
</Button> {source.kind === "mcp" ? "M" : source.kind === "graphql" ? "G" : "A"}
</div> </div>
))} <div className="min-w-0 flex-1">
<div className="text-ui-body font-medium text-foreground">
{source.name}
</div>
<div className="truncate text-ui-body text-muted-foreground/70">
{source.kind.toUpperCase()} · {source.source} ·{" "}
{source.secretConfigured ? (
<Trans>credential saved</Trans>
) : (
<Trans>no auth</Trans>
)}
</div>
</div>
<Button
type="button"
variant="secondary"
className="rounded-full"
size="sm"
disabled={pending === source.id}
onClick={() => void removeSource(source)}
>
{pending === source.id ? <Trans>Removing…</Trans> : <Trans>Remove</Trans>}
</Button>
</div>
))}
{onOpenMcp ? ( {onOpenMcp ? (
<Button <Button
type="button" type="button"

View File

@ -57,7 +57,7 @@ const McpAuthSchema = z
.default({ type: "none" }); .default({ type: "none" });
const McpConfigSchema = z.object({ const McpConfigSchema = z.object({
preset: z.enum(["treg", "custom"]).default("custom"), preset: z.enum(["treg", "github", "custom"]).default("custom"),
auth: McpAuthSchema, auth: McpAuthSchema,
headers: PublicHeadersSchema, headers: PublicHeadersSchema,
}); });

View File

@ -34,7 +34,11 @@ export class ThirdPartyConnectorEmulator {
readonly fetch: typeof globalThis.fetch = async (input, init) => { readonly fetch: typeof globalThis.fetch = async (input, init) => {
const url = urlFromPinnedFetch(input, init); const url = urlFromPinnedFetch(input, init);
if (url.hostname === "api.pipedream.com") return this.pipedream(url, init); if (url.hostname === "api.pipedream.com") return this.pipedream(url, init);
if (url.hostname === "remote.mcp.pipedream.net" || url.hostname === "treg.to") { if (
url.hostname === "remote.mcp.pipedream.net" ||
url.hostname === "treg.to" ||
url.hostname === "api.githubcopilot.com"
) {
return this.mcp(url, init); return this.mcp(url, init);
} }
if (url.hostname === "mcp.example.test" || url.hostname === "executor.example.test") { if (url.hostname === "mcp.example.test" || url.hostname === "executor.example.test") {

View File

@ -0,0 +1,10 @@
/** GitHub's hosted MCP server; a personal access token is all it needs, no app registration. */
export const GITHUB_MCP_SOURCE = "https://api.githubcopilot.com/mcp/";
/** GitHub's token form with evOo's name and the scopes its tools need already filled in. */
export const GITHUB_TOKEN_URL =
"https://github.com/settings/tokens/new?description=evOo&scopes=repo,read:org,workflow";
export function isGithubInstall(install: { kind: string; config: Record<string, unknown> }) {
return install.kind === "mcp" && install.config.preset === "github";
}

View File

@ -21,6 +21,7 @@ export * from "./cron.js";
export * from "./delegated-tasks.js"; export * from "./delegated-tasks.js";
export * from "./events.js"; export * from "./events.js";
export * from "./featured-connectors.js"; export * from "./featured-connectors.js";
export * from "./github-connector.js";
export * from "./group-mentions.js"; export * from "./group-mentions.js";
export * from "./http-response.js"; export * from "./http-response.js";
export * from "./mcp.js"; export * from "./mcp.js";

View File

@ -8,6 +8,7 @@ import {
PipedreamConnector, PipedreamConnector,
ThirdPartyConnectorEmulator, ThirdPartyConnectorEmulator,
} from "@rakazo/adapters"; } from "@rakazo/adapters";
import { GITHUB_MCP_SOURCE } from "@rakazo/core";
import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from "vitest"; import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import type { createApp } from "../../../apps/api/src/app.ts"; import type { createApp } from "../../../apps/api/src/app.ts";
import { sessionCookieHeader } from "./index.js"; import { sessionCookieHeader } from "./index.js";
@ -370,6 +371,43 @@ describeWithDatabase("Composio catalog reconciliation", () => {
); );
}); });
it("connects GitHub's MCP server from a pasted token alone", async () => {
const cookie = await signup(app, `github-connector-${stamp}@rakazo.test`, "GitHub");
await expect(
rpc(app, cookie, "capabilities/install", {
kind: "mcp",
name: "GitHub",
source: GITHUB_MCP_SOURCE,
config: { preset: "github" },
}),
).rejects.toThrow();
const credential = "fake-github-token-value";
const github = await rpc<{
source: string;
secretConfigured: boolean;
config: Record<string, unknown>;
}>(app, cookie, "capabilities/install", {
kind: "mcp",
name: "GitHub",
// The preset pins GitHub's server; a client cannot point it elsewhere.
source: "https://mcp.example.test/mcp",
credential,
config: { preset: "github" },
});
expect(github).toMatchObject({
source: GITHUB_MCP_SOURCE,
secretConfigured: true,
config: { preset: "github", auth: { type: "bearer" } },
});
expect(JSON.stringify(github)).not.toContain(credential);
expect(thirdParties.records).toContainEqual({
provider: "mcp",
operation: "tools/list",
host: "api.githubcopilot.com",
authenticated: true,
});
});
it("installs Treg, Executor, and custom MCP sources and routes their calls", async () => { it("installs Treg, Executor, and custom MCP sources and routes their calls", async () => {
const cookie = await signup(app, `mcp-connectors-${stamp}@rakazo.test`, "MCP Connectors"); const cookie = await signup(app, `mcp-connectors-${stamp}@rakazo.test`, "MCP Connectors");
const actor = await rpc<Actor>(app, cookie, "me"); const actor = await rpc<Actor>(app, cookie, "me");