Skip to content

Commit 80f845b

Browse files
fix(md-exports): apply keyword placeholder defaults in generated markdown
___PUBLIC_DSN___ and related ___KEYWORD___ tokens are replaced client-side by codeKeywords.tsx, so SSR HTML and the generated .md artifacts contain them verbatim. Adds MD_KEYWORD_DEFAULTS (mirroring DEFAULTS.PROJECT[0] in codeContext.tsx) and applies them via applyKeywordDefaults() after the HTML→markdown cache step, so .md files ship with usable example values. Applied outside the cache to avoid invalidating existing cache entries. Fixes #18038 Co-authored-by: David Cramer <david@sentry.io>
1 parent 07bf6f0 commit 80f845b

1 file changed

Lines changed: 57 additions & 4 deletions

File tree

scripts/generate-md-exports.mjs

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,57 @@ import {remove} from 'unist-util-remove';
2929

3030
import {rehypeExpandCodeTabs} from './rehype-expand-code-tabs.mjs';
3131

32+
// Default values for code keyword placeholders (e.g. ___PUBLIC_DSN___) that are
33+
// normally replaced client-side by codeKeywords.tsx. These must stay in sync with
34+
// DEFAULTS.PROJECT[0] in src/components/codeContext.tsx.
35+
// Values must be clearly non-functional so agents and LLMs know they need
36+
// to be replaced with real project-specific values. Avoid realistic-looking
37+
// values (e.g. valid DSN shapes) — agents will use them as-is.
38+
const MD_KEYWORD_DEFAULTS = {
39+
DSN: 'https://<key>@<org>.ingest.sentry.io/<project>',
40+
PUBLIC_DSN: 'https://<key>@<org>.ingest.sentry.io/<project>',
41+
PUBLIC_KEY: '<your-public-key>',
42+
SECRET_KEY: '<your-secret-key>',
43+
API_URL: 'https://sentry.io/api',
44+
PROJECT_ID: '<your-project-id>',
45+
PROJECT_SLUG: '<your-project-slug>',
46+
ORG_ID: '<your-org-id>',
47+
ORG_SLUG: '<your-org-slug>',
48+
ORG_INGEST_DOMAIN: '<org>.ingest.sentry.io',
49+
JS_SDK_LOADER_HOST: 'js.sentry-cdn.com',
50+
MINIDUMP_URL:
51+
'https://<org>.ingest.sentry.io/api/<project>/minidump/?sentry_key=<key>',
52+
UNREAL_URL: 'https://<org>.ingest.sentry.io/api/<project>/unreal/<key>/',
53+
OTLP_URL: 'https://<org>.ingest.sentry.io/api/<project>/integration/otlp',
54+
OTLP_TRACES_URL:
55+
'https://<org>.ingest.sentry.io/api/<project>/integration/otlp/v1/traces',
56+
OTLP_LOGS_URL:
57+
'https://<org>.ingest.sentry.io/api/<project>/integration/otlp/v1/logs',
58+
VERCEL_LOG_DRAIN_URL:
59+
'https://<org>.ingest.sentry.io/api/<project>/integration/vercel/logs/',
60+
};
61+
62+
/**
63+
* Replaces ___KEYWORD___ placeholders in generated markdown with clearly non-functional
64+
* placeholder values (e.g. <your-org-slug>) so agents and LLMs know they must be
65+
* substituted with real project-specific values before use.
66+
*
67+
* These tokens are replaced client-side by codeKeywords.tsx at runtime; the SSR HTML
68+
* (and therefore the generated markdown) contains them verbatim. Using obviously-fake
69+
* values — rather than realistic-looking defaults — prevents agents from silently
70+
* treating them as valid configuration.
71+
*
72+
* Applied after HTML→markdown conversion, outside the cache, so existing cache entries
73+
* remain valid.
74+
*/
75+
function applyKeywordDefaults(markdown) {
76+
let result = markdown;
77+
for (const [key, value] of Object.entries(MD_KEYWORD_DEFAULTS)) {
78+
result = result.replaceAll(`___${key}___`, value);
79+
}
80+
return result;
81+
}
82+
3283
const DOCS_ORIGIN = process.env.NEXT_PUBLIC_DEVELOPER_DOCS
3384
? 'https://develop.sentry.dev'
3485
: 'https://docs.sentry.io';
@@ -1099,10 +1150,12 @@ async function processTaskList({id, tasks, cacheDir, noCache, usedCacheFiles}) {
10991150
cacheMisses.push(relativePath);
11001151
}
11011152

1102-
// Keep metadata outside the cache so description-only changes don't invalidate
1103-
// the expensive HTML → markdown conversion output.
1104-
// Prepend YAML frontmatter and write to target
1105-
const output = frontmatter ? formatYamlFrontmatter(frontmatter) + data : data;
1153+
// Keep these transformations outside the cache so they don't invalidate the
1154+
// expensive HTML → markdown conversion output:
1155+
// - applyKeywordDefaults: replaces ___KEYWORD___ placeholders with defaults
1156+
// - formatYamlFrontmatter: prepends YAML metadata
1157+
const resolved = applyKeywordDefaults(data);
1158+
const output = frontmatter ? formatYamlFrontmatter(frontmatter) + resolved : resolved;
11061159
await writeFile(targetPath, output, {encoding: 'utf8'});
11071160

11081161
if (r2Hash !== null && s3Client) {

0 commit comments

Comments
 (0)