Compare commits

...
3 Commits
15 changed files with 476 additions and 6 deletions

No files matched your search

+2 -2
View File
@@ -274,8 +274,8 @@ The boundary, in brief:
many discovery and page fetches, so each call reports its own request ledger and
the run reports totals.
- **Root-only in routed monorepos** (it starts a host process); scope configs
cannot alter it. Result-cache reuse is disabled while research is enabled,
because web content can change without a config change.
cannot alter it. Research results are fetched and audited per run; cached review
results remain keyed by the ordinary trusted review inputs and make no network call.
Full detail — providers, query grammar, `fetch_platform_doc` modes, provenance and
citation grounding: [LLP 0013](./llp/0013-platform-research.explainer.md).
+10 -1
View File
@@ -228,7 +228,16 @@ the queries and bounded results.
The built-in source catalog covers Apple, Android, platform releases, Swift
Evolution, SDWebImage, Media3, Glide, OkHttp, Kotlin coroutines, Gradle/AGP, selected JetBrains
issues, Expo, React Native, Reanimated, Gesture Handler, Screens, and Worklets.
issues, Expo, React, React Native, WHATWG and W3C web specifications, Chrome DevTools
Protocol, Flow, TypeScript, the Android NDK, CMake, CocoaPods, Metro, Reanimated,
Gesture Handler, Screens, and Worklets. The React Native
additions cover the contracts its implementation must preserve: React semantics, its
web-compatible APIs, the repository's type systems, and its native build and dependency
managers. Hermes documentation is intentionally not fetched from the engine's `main`
branch because it can disagree with React Native's vendored revision. Repository PR and
issue history is intentionally not a
live evidence provider: it belongs in a versioned offline evaluation corpus used to
improve prompts, while the runtime MCP remains an API-contract channel.
The canonical OkHttp host is backed by both the
[maintainer's transfer announcement](https://jakewharton.com/the-lysine-contingency/)
and [Commonhaus's project-transfer record](https://www.commonhaus.org/activity/315.html).
+88
View File
@@ -141,6 +141,94 @@ const cases = [
title: "FlatList",
body: "getItemLayout is an optional optimization for FlatList. It lets the list skip the measurement of dynamic content when the row height is known ahead of time.",
},
{
label: "react",
provider: "react",
platform: "react-native",
providers: ["react"],
query: "useEffect dependency array",
expected: "react.dev/reference/react/useEffect",
url: "https://react.dev/reference/react/useEffect",
title: "useEffect",
body: "useEffect synchronizes a component with an external system. Every reactive value read by the effect belongs in its dependency array.",
},
{
label: "flow",
provider: "flow",
platform: "react-native",
providers: ["flow"],
query: "exact object types",
expected: "flow.org/en/docs/types/objects",
url: "https://flow.org/en/docs/types/objects/",
title: "Object Types",
body: "An exact object type rejects extra properties. Flow object types are exact by default unless they are explicitly declared inexact.",
},
{
label: "typescript",
provider: "typescript",
platform: "react-native",
providers: ["typescript"],
query: "declaration file module exports",
expected: "typescriptlang.org/docs/handbook/declaration-files",
url: "https://www.typescriptlang.org/docs/handbook/declaration-files/templates/module-d-ts.html",
title: "Modules .d.ts",
body: "A module declaration file describes the runtime exports of a JavaScript module. Its export shape must match the values consumers can import.",
},
{
label: "web-standards",
provider: "web-standards",
platform: "react-native",
providers: ["web-standards"],
sourceKind: "standard",
query: "AbortSignal fetch cancellation",
expected: "fetch.spec.whatwg.org",
url: "https://fetch.spec.whatwg.org/",
title: "Fetch Standard",
body: "An AbortSignal can abort a fetch operation. The fetch promise rejects when the request is terminated by the signal.",
},
{
label: "chrome-devtools-protocol",
provider: "chrome-devtools-protocol",
platform: "react-native",
providers: ["chrome-devtools-protocol"],
sourceKind: "standard",
query: "Runtime evaluate awaitPromise",
expected: "chromedevtools.github.io/devtools-protocol/tot/Runtime",
url: "https://chromedevtools.github.io/devtools-protocol/tot/Runtime/",
title: "Runtime domain",
body: "Runtime.evaluate evaluates an expression on the inspected page. The awaitPromise option waits for a returned promise and reports its resolved result.",
},
{
label: "android-ndk",
provider: "android-ndk",
providers: ["android-ndk"],
query: "JNIEnv local references",
expected: "developer.android.com/ndk/guides/jni-tips",
url: "https://developer.android.com/ndk/guides/jni-tips",
title: "JNI tips",
body: "JNI local references are valid only for the duration of the current native method call and on the current thread. Long-lived references must be promoted to global references.",
},
{
label: "cmake",
provider: "cmake",
providers: ["cmake"],
query: "target_link_libraries transitive",
expected: "cmake.org/cmake/help/latest/command/target_link_libraries",
url: "https://cmake.org/cmake/help/latest/command/target_link_libraries.html",
title: "target_link_libraries",
body: "target_link_libraries links a target to libraries and can publish transitive link dependencies through the target's interface.",
},
{
label: "cocoapods",
provider: "cocoapods",
platform: "apple",
providers: ["cocoapods"],
query: "Podfile use_frameworks linkage",
expected: "guides.cocoapods.org/syntax/podfile",
url: "https://guides.cocoapods.org/syntax/podfile.html",
title: "Podfile Syntax Reference",
body: "The use_frameworks directive configures pods to build as frameworks and accepts a linkage option for static or dynamic frameworks.",
},
{
label: "react-native-reanimated",
provider: "react-native-reanimated",
+46
View File
@@ -285,6 +285,52 @@ test("parseClaudeResult: success maps text/cost/tokens/model", () => {
expect(r.structuredOutputFailure).toBe(false);
});
test("parseClaudeResult: records thinking tokens as reasoning, without inflating output", () => {
const stdout = JSON.stringify({
type: "result",
subtype: "success",
is_error: false,
result: "the findings",
total_cost_usd: 0.5,
usage: {
input_tokens: 10,
output_tokens: 200,
output_tokens_details: { thinking_tokens: 170 },
cache_creation_input_tokens: 0,
cache_read_input_tokens: 0,
},
});
const r = parseClaudeResult(stdout);
expect(r.tokens.reasoning).toBe(170);
expect(r.tokens.output).toBe(200);
});
test("parseClaudeResult: omits reasoning when the CLI reports no breakdown", () => {
const stdout = JSON.stringify({
type: "result",
subtype: "success",
is_error: false,
result: "the findings",
total_cost_usd: 0.5,
usage: { input_tokens: 10, output_tokens: 200 },
});
expect(parseClaudeResult(stdout).tokens.reasoning).toBeUndefined();
});
test("parseClaudeResult: survives a null/!object output_tokens_details", () => {
for (const details of [null, "nope", 7]) {
const stdout = JSON.stringify({
type: "result",
subtype: "success",
is_error: false,
result: "x",
total_cost_usd: 0,
usage: { input_tokens: 1, output_tokens: 2, output_tokens_details: details },
});
expect(parseClaudeResult(stdout).tokens.reasoning).toBeUndefined();
}
});
test("parseClaudeResult: reads the final result from stream-json JSONL", () => {
const stdout = [
JSON.stringify({ type: "system", subtype: "init", model: "claude-opus-5" }),
@@ -221,4 +221,16 @@ test("direct URL inference prefers narrow release and dependency providers", ()
"https://developer.android.com/reference/androidx/media3/common/Player",
).provider,
).toBe("media3");
expect(
resolveDirectDocumentationTarget("https://developer.android.com/ndk/guides/cpp-support"),
).toMatchObject({ provider: "android-ndk", sourceKind: "official-guide" });
expect(resolveDirectDocumentationTarget("https://fetch.spec.whatwg.org/")).toMatchObject({
provider: "web-standards",
sourceKind: "standard",
});
expect(
resolveDirectDocumentationTarget(
"https://chromedevtools.github.io/devtools-protocol/tot/Runtime/",
),
).toMatchObject({ provider: "chrome-devtools-protocol", sourceKind: "standard" });
});
+13 -1
View File
@@ -39,12 +39,18 @@ test("stdio MCP advertises the read-only documentation tools and their enforced
);
expect(searchTool?.description ?? "").toContain("Native source retains platform context");
expect(searchTool?.description ?? "").toContain("react-native-worklets=Worklets");
expect(searchTool?.description ?? "").toContain("metro=Metro bundler");
expect(searchTool?.description ?? "").toContain(
"web-standards=WHATWG and W3C web platform standards",
);
expect(searchTool?.description ?? "").toContain("android-ndk=Android NDK");
expect(fetchTool?.annotations?.readOnlyHint).toBe(true);
expect(fetchTool?.description ?? "").toMatch(/every redirect/);
const inputSchema = searchTool?.inputSchema as {
properties?: {
query?: { description?: string };
providers?: { description?: string };
providers?: { description?: string; items?: { enum?: string[] } };
sourceKinds?: { description?: string; items?: { enum?: string[] } };
};
};
const fetchInputSchema = fetchTool?.inputSchema as {
@@ -59,6 +65,12 @@ test("stdio MCP advertises the read-only documentation tools and their enforced
expect(inputSchema.properties?.providers?.description ?? "").toContain(
"jetbrains-issues=JetBrains YouTrack context",
);
expect(inputSchema.properties?.providers?.items?.enum).toContain("typescript");
expect(inputSchema.properties?.providers?.items?.enum).toContain("chrome-devtools-protocol");
expect(inputSchema.properties?.sourceKinds?.items?.enum).toContain("standard");
expect(inputSchema.properties?.sourceKinds?.description ?? "").toContain(
"external compatibility specification",
);
expect(fetchInputSchema.properties?.context?.default).toBe("section");
expect(fetchInputSchema.properties?.context?.description ?? "").toContain(
"document=bounded extracted page text",
@@ -1,22 +1,31 @@
import { expect, test } from "bun:test";
import {
androidNdkProvider,
androidProvider,
appleProvider,
appleReleasesProvider,
chromeDevtoolsProtocolProvider,
cmakeProvider,
cocoaPodsProvider,
expoProvider,
flowProvider,
glideProvider,
jetbrainsIssuesProvider,
metroProvider,
okHttpProvider,
reactNativeGestureHandlerProvider,
reactNativeProvider,
reactNativeReanimatedProvider,
reactNativeScreensProvider,
reactNativeWorkletsProvider,
reactProvider,
resolveAllowedUrl,
resolveAllowedRequestUrl,
sdWebImageProvider,
swiftEvolutionProvider,
typescriptProvider,
webStandardsProvider,
} from "../../research-mcp/providers.js";
test("Apple provider accepts only HTTPS documentation paths on the exact host", () => {
@@ -180,6 +189,7 @@ test("React Native ecosystem providers stay on their exact documentation hosts a
reactNativeWorkletsProvider,
"https://docs.swmansion.com/react-native-worklets/docs/fundamentals/getting-started/",
],
[metroProvider, "https://metrobundler.dev/docs/configuration"],
] as const) {
expect(resolveAllowedUrl(provider, url).hostname).toBe(new URL(url).hostname);
}
@@ -193,4 +203,53 @@ test("React Native ecosystem providers stay on their exact documentation hosts a
expect(() => resolveAllowedUrl(expoProvider, "https://expo.dev/accounts")).toThrow(
/outside the expo documentation allowlist/,
);
expect(() =>
resolveAllowedUrl(metroProvider, "https://metrobundler.dev.evil.example/docs/configuration"),
).toThrow(/outside the metro documentation allowlist/);
});
test("React Native contract providers admit only their fixed authoritative corpora", () => {
for (const [provider, url] of [
[reactProvider, "https://react.dev/reference/react/useEffect"],
[flowProvider, "https://flow.org/en/docs/types/unions/"],
[typescriptProvider, "https://www.typescriptlang.org/docs/handbook/declaration-files/"],
[androidNdkProvider, "https://developer.android.com/ndk/guides/cpp-support"],
[cmakeProvider, "https://cmake.org/cmake/help/v3.31/command/add_library.html"],
[cocoaPodsProvider, "https://guides.cocoapods.org/syntax/podfile.html"],
[webStandardsProvider, "https://fetch.spec.whatwg.org/"],
[webStandardsProvider, "https://w3c.github.io/IntersectionObserver/"],
[
chromeDevtoolsProtocolProvider,
"https://chromedevtools.github.io/devtools-protocol/tot/Runtime/",
],
] as const) {
expect(resolveAllowedUrl(provider, url).hostname).toBe(new URL(url).hostname);
}
for (const [provider, url] of [
[reactProvider, "https://react.dev/reference/react-dom/components/form"],
[reactProvider, "https://react.dev/learn/escape-hatches"],
[flowProvider, "https://flow.org/blog/"],
[typescriptProvider, "https://www.typescriptlang.org/play"],
[androidNdkProvider, "https://developer.android.com/studio/projects/install-ndk"],
[cmakeProvider, "https://cmake.org/community/"],
[cocoaPodsProvider, "https://guides.cocoapods.org/blog/"],
[webStandardsProvider, "https://w3c.github.io/permissions/"],
[webStandardsProvider, "https://whatwg.org/"],
[chromeDevtoolsProtocolProvider, "https://chromedevtools.github.io/debugger-protocol-viewer/"],
] as const) {
expect(() => resolveAllowedUrl(provider, url)).toThrow(
/outside the .* documentation allowlist/,
);
}
expect(() =>
resolveAllowedUrl(webStandardsProvider, "https://user:[email protected]/"),
).toThrow(/outside the web-standards documentation allowlist/);
expect(() =>
resolveAllowedUrl(androidNdkProvider, "https://developer.android.com.evil.example/ndk/guides"),
).toThrow(/outside the android-ndk documentation allowlist/);
expect(() =>
resolveAllowedUrl(reactNativeProvider, "https://reactnative.dev/contributing/overview"),
).toThrow(/outside the react-native documentation allowlist/);
});
@@ -299,3 +299,67 @@ test("Apple release searches select the platform-specific fixed scope", async ()
expect(queries[0]).toContain("site:developer.apple.com/documentation/xcode-release-notes");
expect(queries[1]).toContain("site:developer.apple.com/documentation/ios-ipados-release-notes");
});
test("web standards discovery uses fixed WHATWG and W3C scopes with standards provenance", async () => {
let searchRequests = 0;
const fetchImplementation = async (input: string | URL | Request): Promise<Response> => {
const url = new URL(input instanceof Request ? input.url : input.toString());
if (url.hostname === "api.search.brave.com") {
searchRequests++;
const query = url.searchParams.get("q") ?? "";
expect(query).toContain("site:whatwg.org");
expect(query).toContain("site:w3c.github.io");
return jsonResponse({
web: {
results: [
{ title: "Fetch Standard", url: "https://fetch.spec.whatwg.org/" },
{ title: "Unrelated W3C draft", url: "https://w3c.github.io/permissions/" },
],
},
});
}
expect(url.href).toBe("https://fetch.spec.whatwg.org/");
return new Response(
"<!doctype html><html><head><title>Fetch Standard</title></head><body><main>" +
"<h1>Fetch</h1><p>The AbortSignal controls cancellation of a fetch request and " +
"causes the fetch promise to reject when the operation is terminated.</p>" +
"</main></body></html>",
{ headers: { "content-type": "text/html; charset=utf-8" } },
);
};
const response = await searchRemoteDocumentation(
"web-standards",
"AbortSignal fetch cancellation",
2,
{ apiKey: "test-key", fetchImplementation, sourceKinds: ["standard"] },
);
expect(searchRequests).toBe(1);
expect(response.warnings).toEqual([]);
expect(response.results).toHaveLength(1);
expect(response.results[0]).toMatchObject({
provider: "web-standards",
sourceKind: "standard",
url: "https://fetch.spec.whatwg.org/",
});
});
test("provenance filtering skips a standards provider before network access", async () => {
let requests = 0;
const response = await searchRemoteDocumentation(
"chrome-devtools-protocol",
"Runtime evaluate",
1,
{
apiKey: "test-key",
sourceKinds: ["official-api"],
fetchImplementation: async () => {
requests++;
return jsonResponse({ web: { results: [] } });
},
},
);
expect(requests).toBe(0);
expect(response).toEqual({ results: [], warnings: [] });
});
@@ -149,6 +149,40 @@ test("search filters named corpora and provenance classes", () => {
]);
});
test("search filters external standards separately from implementation documentation", () => {
const index = buildSearchIndex([
{
id: "standard:fetch",
platform: "react-native",
provider: "web-standards",
sourceKind: "standard",
title: "Fetch Standard",
url: "https://fetch.spec.whatwg.org/",
passage: "AbortSignal controls cancellation of a fetch request.",
indexedAt: "2026-08-06T00:00:00.000Z",
},
{
id: "rn:fetch",
platform: "react-native",
provider: "react-native",
sourceKind: "official-api",
title: "React Native global fetch",
url: "https://reactnative.dev/docs/global-fetch",
passage: "React Native exposes fetch as a global API.",
indexedAt: "2026-08-06T00:00:00.000Z",
},
]);
const results = searchDocumentation(index, "fetch AbortSignal", {
platform: "react-native",
sourceKinds: ["standard"],
limit: 5,
});
expect(results.map(({ provider, sourceKind }) => ({ provider, sourceKind }))).toEqual([
{ provider: "web-standards", sourceKind: "standard" },
]);
});
test("a language filter excludes otherwise matching untagged documents", () => {
const index = buildSearchIndex([
...chunks,
+3
View File
@@ -582,6 +582,9 @@ export function parseClaudeResult(stdout: string): ClaudeResult {
const tokens: TokenUsage = {
input: num(usage.input_tokens),
output: num(usage.output_tokens),
reasoning: num(
(usage.output_tokens_details as Record<string, unknown> | null | undefined)?.thinking_tokens,
),
cache: {
write: num(usage.cache_creation_input_tokens),
read: num(usage.cache_read_input_tokens),
+18
View File
@@ -22,17 +22,26 @@ const DIRECT_PROVIDER_ORDER: readonly ProviderId[] = [
"android-releases",
"media3",
"agp",
"android-ndk",
"android",
"glide",
"okhttp",
"kotlin-coroutines",
"gradle",
"jetbrains-issues",
"react",
"web-standards",
"chrome-devtools-protocol",
"flow",
"typescript",
"cmake",
"cocoapods",
"react-native-reanimated",
"react-native-gesture-handler",
"react-native-screens",
"react-native-worklets",
"react-native",
"metro",
"expo",
];
@@ -49,13 +58,22 @@ const DIRECT_SOURCE_KIND: Record<ProviderId, SourceKind> = {
"kotlin-coroutines": "official-guide",
gradle: "official-guide",
agp: "release-notes",
"android-ndk": "official-guide",
"jetbrains-issues": "issue-tracker",
expo: "official-api",
react: "official-api",
"react-native": "official-api",
"web-standards": "standard",
"chrome-devtools-protocol": "standard",
flow: "official-guide",
typescript: "official-guide",
cmake: "official-guide",
cocoapods: "official-guide",
"react-native-reanimated": "official-guide",
"react-native-gesture-handler": "official-guide",
"react-native-screens": "official-guide",
"react-native-worklets": "official-guide",
metro: "official-guide",
};
export interface DirectDocumentationTarget {
+77
View File
@@ -345,6 +345,10 @@ export const expoProvider = htmlProvider("expo", "react-native", "Expo documenta
{ hostname: "docs.expo.dev", prefixes: [""] },
]);
export const reactProvider = htmlProvider("react", "react-native", "React documentation", [
{ hostname: "react.dev", prefixes: ["/reference/react", "/reference/rules"] },
]);
export const reactNativeProvider = htmlProvider(
"react-native",
"react-native",
@@ -357,6 +361,66 @@ export const reactNativeProvider = htmlProvider(
],
);
export const webStandardsProvider = htmlProvider(
"web-standards",
"react-native",
"Web platform standards",
[
{ hostname: "fetch.spec.whatwg.org", prefixes: [""] },
{ hostname: "xhr.spec.whatwg.org", prefixes: [""] },
{ hostname: "websockets.spec.whatwg.org", prefixes: [""] },
{ hostname: "dom.spec.whatwg.org", prefixes: [""] },
{ hostname: "streams.spec.whatwg.org", prefixes: [""] },
{ hostname: "url.spec.whatwg.org", prefixes: [""] },
{ hostname: "encoding.spec.whatwg.org", prefixes: [""] },
{ hostname: "console.spec.whatwg.org", prefixes: [""] },
{ hostname: "html.spec.whatwg.org", prefixes: ["/multipage"] },
{
hostname: "w3c.github.io",
prefixes: [
"/FileAPI",
"/hr-time",
"/performance-timeline",
"/resource-timing",
"/IntersectionObserver",
],
},
],
);
export const chromeDevtoolsProtocolProvider = htmlProvider(
"chrome-devtools-protocol",
"react-native",
"Chrome DevTools Protocol documentation",
[{ hostname: "chromedevtools.github.io", prefixes: ["/devtools-protocol"] }],
);
export const flowProvider = htmlProvider("flow", "react-native", "Flow documentation", [
{ hostname: "flow.org", prefixes: ["/en/docs"] },
]);
export const typescriptProvider = htmlProvider(
"typescript",
"react-native",
"TypeScript documentation",
[{ hostname: "www.typescriptlang.org", prefixes: ["/docs"] }],
);
export const androidNdkProvider = htmlProvider(
"android-ndk",
"android",
"Android NDK documentation",
[{ hostname: "developer.android.com", prefixes: ["/ndk"] }],
);
export const cmakeProvider = htmlProvider("cmake", "android", "CMake documentation", [
{ hostname: "cmake.org", prefixes: ["/cmake/help"] },
]);
export const cocoaPodsProvider = htmlProvider("cocoapods", "apple", "CocoaPods guides", [
{ hostname: "guides.cocoapods.org", prefixes: ["/syntax", "/using"] },
]);
export const reactNativeReanimatedProvider = htmlProvider(
"react-native-reanimated",
"react-native",
@@ -431,6 +495,10 @@ export const reactNativeWorkletsProvider = htmlProvider(
true,
);
export const metroProvider = htmlProvider("metro", "react-native", "Metro bundler documentation", [
{ hostname: "metrobundler.dev", prefixes: [""] },
]);
const providers: Record<ProviderId, DocumentationProvider> = {
apple: appleProvider,
"apple-releases": appleReleasesProvider,
@@ -446,11 +514,20 @@ const providers: Record<ProviderId, DocumentationProvider> = {
agp: agpProvider,
"jetbrains-issues": jetbrainsIssuesProvider,
expo: expoProvider,
react: reactProvider,
"react-native": reactNativeProvider,
"web-standards": webStandardsProvider,
"chrome-devtools-protocol": chromeDevtoolsProtocolProvider,
flow: flowProvider,
typescript: typescriptProvider,
"android-ndk": androidNdkProvider,
cmake: cmakeProvider,
cocoapods: cocoaPodsProvider,
"react-native-reanimated": reactNativeReanimatedProvider,
"react-native-gesture-handler": reactNativeGestureHandlerProvider,
"react-native-screens": reactNativeScreensProvider,
"react-native-worklets": reactNativeWorkletsProvider,
metro: metroProvider,
};
export function getProvider(provider: ProviderId): DocumentationProvider {
+36
View File
@@ -71,10 +71,42 @@ const providerSearchDefinitions: Record<Exclude<ProviderId, "expo">, ProviderSea
scopes: ["youtrack.jetbrains.com/issue"],
sourceKind: "issue-tracker",
},
react: {
scopes: ["react.dev/reference/react", "react.dev/reference/rules"],
sourceKind: "official-api",
},
"react-native": {
scopes: ["reactnative.dev"],
sourceKind: "official-api",
},
"web-standards": {
scopes: ["whatwg.org", "w3c.github.io"],
sourceKind: "standard",
},
"chrome-devtools-protocol": {
scopes: ["chromedevtools.github.io/devtools-protocol"],
sourceKind: "standard",
},
flow: {
scopes: ["flow.org/en/docs"],
sourceKind: "official-guide",
},
typescript: {
scopes: ["typescriptlang.org/docs"],
sourceKind: "official-guide",
},
"android-ndk": {
scopes: ["developer.android.com/ndk"],
sourceKind: "official-guide",
},
cmake: {
scopes: ["cmake.org/cmake/help/latest"],
sourceKind: "official-guide",
},
cocoapods: {
scopes: ["guides.cocoapods.org/syntax", "guides.cocoapods.org/using"],
sourceKind: "official-guide",
},
"react-native-reanimated": {
scopes: ["docs.swmansion.com/react-native-reanimated/docs"],
sourceKind: "official-api",
@@ -91,6 +123,10 @@ const providerSearchDefinitions: Record<Exclude<ProviderId, "expo">, ProviderSea
scopes: ["docs.swmansion.com/react-native-worklets/docs"],
sourceKind: "official-api",
},
metro: {
scopes: ["metrobundler.dev/docs"],
sourceKind: "official-guide",
},
};
export interface RemoteSearchOptions {
+4 -2
View File
@@ -25,7 +25,7 @@ const queryGuidance =
"Formulate short documentation queries from exact API symbols plus one behavior or constraint term. Good: `CameraView barcodeScannerSettings`, `NWPathMonitor pathUpdateHandler`, `GestureDetector simultaneous gestures`. Avoid questions, prose, package/import names, code snippets, literals, paths, credentials, and other sensitive context. If the first result is broad, retry with a narrower symbol or member name.";
const providerGuidance =
"Provider map: apple=Apple SDK APIs and Human Interface Guidelines; apple-releases=Xcode and Apple platform release notes; swift-evolution=Swift Evolution proposals; sdwebimage=SDWebImage APIs and caching/loading behavior; android=Android, Jetpack, Compose, and Google Play services APIs; android-releases=Android platform releases and behavior changes; media3=Jetpack Media3; glide=Glide; okhttp=OkHttp; kotlin-coroutines=Kotlin coroutines; gradle=Gradle; agp=Android Gradle Plugin; jetbrains-issues=JetBrains YouTrack context; expo=Expo documentation; react-native=React Native core; react-native-reanimated=Reanimated; react-native-gesture-handler=Gesture Handler; react-native-screens=Screens; react-native-worklets=Worklets. Native source retains platform context: use apple/android for OS contracts and add the dependency provider for dependency-owned behavior; an Expo package path does not make a native API an Expo-docs query. Issue-tracker results are context, not API contracts.";
"Provider map: apple=Apple SDK APIs and Human Interface Guidelines; apple-releases=Xcode and Apple platform release notes; swift-evolution=Swift Evolution proposals; sdwebimage=SDWebImage APIs and caching/loading behavior; android=Android, Jetpack, Compose, and Google Play services APIs; android-releases=Android platform releases and behavior changes; android-ndk=Android NDK; media3=Jetpack Media3; glide=Glide; okhttp=OkHttp; kotlin-coroutines=Kotlin coroutines; gradle=Gradle; agp=Android Gradle Plugin; jetbrains-issues=JetBrains YouTrack context; expo=Expo documentation; react=React APIs and semantics; react-native=React Native core documentation; web-standards=WHATWG and W3C web platform standards; chrome-devtools-protocol=Chrome DevTools Protocol; flow=Flow type-system documentation; typescript=TypeScript declaration semantics; cmake=CMake build-system documentation; cocoapods=CocoaPods integration guides; react-native-reanimated=Reanimated; react-native-gesture-handler=Gesture Handler; react-native-screens=Screens; react-native-worklets=Worklets; metro=Metro bundler. Native source retains platform context: use apple/android for OS contracts and add the dependency, build-tool, type-system, or web-contract provider for behavior that source owns; repository ownership does not make a native API a React Native or Expo documentation query. Standards describe compatibility targets; confirm the reviewed implementation claims that target before applying them. Issue-tracker results are context, not API contracts.";
export interface DocumentationServerOptions {
braveApiKey?: string;
@@ -84,7 +84,9 @@ export async function createDocumentationServer(options: DocumentationServerOpti
.min(1)
.max(SOURCE_KINDS.length)
.optional()
.describe("Optional provenance classes to search"),
.describe(
"Optional provenance classes to search; standard denotes an external compatibility specification rather than an implementation-specific API page",
),
},
annotations: {
readOnlyHint: true,
+10
View File
@@ -18,11 +18,20 @@ export const PROVIDERS = [
"agp",
"jetbrains-issues",
"expo",
"react",
"react-native",
"web-standards",
"chrome-devtools-protocol",
"flow",
"typescript",
"android-ndk",
"cmake",
"cocoapods",
"react-native-reanimated",
"react-native-gesture-handler",
"react-native-screens",
"react-native-worklets",
"metro",
] as const;
export type ProviderId = (typeof PROVIDERS)[number];
@@ -30,6 +39,7 @@ export type ProviderId = (typeof PROVIDERS)[number];
export const SOURCE_KINDS = [
"official-api",
"official-guide",
"standard",
"release-notes",
"issue-tracker",
] as const;