Merge origin/master into provider routing connections

This commit is contained in:
Dotta committed 2026-10-05 21:10:55 -05:00
commit b6bc28667e
627 files changed
+97335 -5708

No files matched your search

+19
View File
@@ -1130,6 +1130,10 @@ const specialMethodsFor = (entry) => {
apiKeyMethodFor(entry, "mcp-api-key", entry.serverUrl, {
guidanceMd: `Open the ${entry.name} dashboard, create an API key for the account agents should use, and paste it below.`,
consoleLinks: { keys: entry.slug === "mem0" ? "https://app.mem0.ai/dashboard/api-keys" : "https://app.honcho.dev", docs: entry.docsUrl },
...(entry.slug === "honcho" ? { tenantFields: [{
key: "workspaceId", label: "Honcho workspace", type: "text", required: true,
placeholder: "Workspace ID", validation: { maxLength: 512 },
}] } : {}),
}),
];
if (entry.slug === "zep") return [oauthMethodFor(entry, "mcp-oauth", entry.serverUrl, {
@@ -1778,6 +1782,21 @@ for (const app of apps) {
}
}
// Reviewed instruction templates are authored in each app's definition. Keep
// that optional capability intact when regenerating its transport/auth fields.
for (const app of apps) {
const definitionPath = path.join(out, `${app.slug}.json`);
if (!fs.existsSync(definitionPath)) continue;
const { agentInstructions: template } = JSON.parse(fs.readFileSync(definitionPath, "utf8"));
if (template === undefined) continue;
if (!template || typeof template.id !== "string" || !template.id.trim() || template.id.length > 160
|| !Number.isInteger(template.version) || template.version < 1
|| typeof template.text !== "string" || !template.text.trim() || template.text.length > 2000) {
throw new Error(`${app.slug}: invalid agent instruction template`);
}
app.agentInstructions = template;
}
const validateApp = (app) => {
if (
app.schemaVersion !== 1 ||
+1 -1
View File
@@ -100,7 +100,7 @@ try {
if (!request.reservationId || request.maxCostUsd !== 0.5 || !["gpt-5.6-luna", "claude-sonnet-5", ...OPENROUTER_MODELS].includes(request.model)) throw new Error("Paid attempt requires ledger reservation and qualified model");
if (isOpenRouter) {
providerVersion = execFileSync(resolve("packages/paperclip-runner/node_modules/opencode-ai/bin/opencode.exe"), ["--version"], { encoding: "utf8" }).trim();
if (providerVersion !== "1.18.32") throw new Error("OpenCode profile requires version 1.18.32");
if (providerVersion !== "1.18.34") throw new Error("OpenCode profile requires version 1.18.34");
}
const providerEnvironment = isOpenRouter ? openRouterEnvironment() : request.model === "claude-sonnet-5" ? (() => {
const token = process.env.CLAUDE_CODE_OAUTH_TOKEN;
@@ -1,7 +1,7 @@
// Opt-in real Codex qualification; no model turn or live account data.
// Run from the repository root:
// node --import ./server/node_modules/tsx/dist/loader.mjs scripts/tests/native-cleanup-paginated-codex.mjs
// PAPERCLIP_TEST_CODEX_BINARY may select the exact installed Codex 0.156.0 binary.
// PAPERCLIP_TEST_CODEX_BINARY may select the exact installed Codex 0.160.0 binary.
// Fresh synthetic fixture directories are retained for inspection; never reuse live homes.
import { spawn, execFileSync } from "node:child_process";
import {
@@ -26,10 +26,10 @@ if (
execFileSync(codexBinary, ["--version"], {
encoding: "utf8",
timeout: 10000,
}).trim() !== "codex-cli 0.156.0"
}).trim() !== "codex-cli 0.160.0"
) {
throw new Error(
"This opt-in qualification requires Codex CLI 0.156.0. Requalify deliberately before changing the pin.",
"This opt-in qualification requires Codex CLI 0.160.0. Requalify deliberately before changing the pin.",
);
}
const home = await mkdtemp(join(tmpdir(), "paperclip-paginated-probe-"));
@@ -132,7 +132,7 @@ const lines =
timestamp,
cwd: home,
originator: "codex",
cli_version: "0.156.0",
cli_version: "0.160.0",
source: "cli",
model_provider: "openai",
selected_capability_roots: [],
@@ -88,7 +88,7 @@ if (args.length === 0 || (args.length === 1 && args[0] === "--help")) {
}).trim();
assert.equal(
version,
"codex-cli 0.156.0",
"codex-cli 0.160.0",
"qualified_codex_version_required",
);
const ledger = join(fixture, "provider-process-starts.txt");
@@ -309,7 +309,7 @@ if (args.length === 0 || (args.length === 1 && args[0] === "--help")) {
kind: "codex",
provider: "codex",
driver: "codex_app_server",
providerVersion: "0.156.0",
providerVersion: "0.160.0",
command: shim,
args: [
"--cd",
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env node
// Refresh only Arcade's public support claim; never update Composio verification dates.
import { readFile, writeFile } from "node:fs/promises";
const source = "https://docs.arcade.dev/en/resources/integrations";
const args = process.argv.slice(2);
const verifiedAt = args[args.indexOf("--verified-at") + 1];
if (!args.includes("--verified-at") || !/^\d{4}-\d{2}-\d{2}$/.test(verifiedAt)) {
throw new Error("Supply --verified-at YYYY-MM-DD after reviewing the official public Arcade catalog.");
}
const input = args.includes("--input") ? args[args.indexOf("--input") + 1] : null;
let html;
if (input) html = await readFile(input, "utf8");
else {
const response = await fetch(source);
if (!response.ok) throw new Error(`Arcade catalog request failed (${response.status})`);
html = await response.text();
}
const records = [...html.matchAll(/self\.__next_f\.push\(\[1,("(?:\\.|[^"\\])*?")\]\)/g)]
.map((match) => JSON.parse(match[1])).join("");
const start = records.indexOf('"toolkits":[');
if (start < 0) throw new Error("Arcade catalog payload was not found; preserve the previous snapshot.");
const rest = records.slice(start + '"toolkits":'.length);
let end = 0, depth = 0, quoted = false, escaped = false;
for (; end < rest.length; end++) {
const char = rest[end];
if (escaped) { escaped = false; continue; }
if (quoted && char === "\\") { escaped = true; continue; }
if (char === '"') { quoted = !quoted; continue; }
if (!quoted && char === "[") depth++;
if (!quoted && char === "]" && --depth === 0) { end++; break; }
}
const toolkits = JSON.parse(rest.slice(0, end));
const apps = toolkits.filter((app) => app.isComingSoon === false && app.isHidden === false).map((app) => {
const toolkit = app.relativeDocsLink.split("/").at(-1);
const slug = toolkit.replaceAll("_", "-");
const logoUrl = new URL(app.publicIconUrl, source);
const docsUrl = new URL(app.hasPage ? app.docsLink : source);
if (!/^[a-z0-9-]+$/.test(slug) || !app.label || typeof app.id !== "string"
|| logoUrl.protocol !== "https:" || !["docs.arcade.dev", "design-system.arcade.dev"].includes(logoUrl.hostname)
|| docsUrl.origin !== "https://docs.arcade.dev") throw new Error(`Invalid public Arcade entry: ${app.id}`);
return { slug, toolkit, name: app.label, logoUrl: logoUrl.href, docsUrl: docsUrl.href, aliases: [app.id, toolkit], category: app.category };
}).sort((a, b) => a.slug.localeCompare(b.slug, "en"));
if (apps.length < 100 || new Set(apps.map((app) => app.slug)).size !== apps.length) {
throw new Error("Arcade catalog is incomplete or contains duplicate slugs; preserve the previous snapshot.");
}
const target = new URL("../packages/shared/src/arcade-app-catalog.json", import.meta.url);
await writeFile(target, `${JSON.stringify({ source, verifiedAt, apps }, null, 2)}\n`);
console.log(`Indexed ${apps.length} public Arcade apps (${verifiedAt}).`);