MCPcopy Index your code
hub / github.com/garrytan/gstack / transformFrontmatter

Function transformFrontmatter

scripts/gen-skill-docs.ts:510–602  ·  view source on GitHub ↗

* Transform frontmatter for external hosts. * Claude: strips `sensitive:` field (only Factory uses it). * Codex: keeps name + description only, enforces 1024-char limit. * Factory: keeps name + description + user-invocable, conditionally adds disable-model-invocation.

(content: string, host: Host)

Source from the content-addressed store, hash-verified

508 * Factory: keeps name + description + user-invocable, conditionally adds disable-model-invocation.
509 */
510function transformFrontmatter(content: string, host: Host): string {
511 const hostConfig = getHostConfig(host);
512 const fm = hostConfig.frontmatter;
513
514 if (fm.mode === 'denylist') {
515 // Denylist mode: strip listed fields, keep everything else
516 for (const field of fm.stripFields || []) {
517 if (field === 'voice-triggers') {
518 content = content.replace(/^voice-triggers:\n(?:\s+-\s+"[^"]*"\n?)*/m, '');
519 } else {
520 content = content.replace(new RegExp(`^${field}:\\s*.*\\n`, 'm'), '');
521 }
522 }
523 return content;
524 }
525
526 // Allowlist mode: reconstruct frontmatter with only allowed fields
527 const fmStart = content.indexOf('---\n');
528 if (fmStart !== 0) return content;
529 const fmEnd = content.indexOf('\n---', fmStart + 4);
530 if (fmEnd === -1) return content;
531 const frontmatter = content.slice(fmStart + 4, fmEnd);
532 const body = content.slice(fmEnd + 4);
533 const { name, description } = extractNameAndDescription(content);
534
535 // Description limit enforcement
536 if (fm.descriptionLimit) {
537 const behavior = fm.descriptionLimitBehavior || 'error';
538 if (description.length > fm.descriptionLimit) {
539 if (behavior === 'error') {
540 throw new Error(
541 `${hostConfig.displayName} description for "${name}" is ${description.length} chars (max ${fm.descriptionLimit}). ` +
542 `Compress the description in the .tmpl file.`
543 );
544 } else if (behavior === 'warn') {
545 console.warn(`WARNING: ${hostConfig.displayName} description for "${name}" exceeds ${fm.descriptionLimit} chars`);
546 }
547 // 'truncate' — silently proceed
548 }
549 }
550
551 // Build frontmatter with allowed fields
552 const indentedDesc = description.split('\n').map(l => ` ${l}`).join('\n');
553 let newFm = `---\nname: ${name}\ndescription: |\n${indentedDesc}\n`;
554
555 // Add extra fields (host-wide)
556 if (fm.extraFields) {
557 for (const [key, value] of Object.entries(fm.extraFields)) {
558 if (key !== 'name' && key !== 'description') {
559 newFm += `${key}: ${value}\n`;
560 }
561 }
562 }
563
564 // Add conditional fields
565 if (fm.conditionalFields) {
566 for (const rule of fm.conditionalFields) {
567 const match = Object.entries(rule.if).every(([k, v]) =>

Callers 2

processExternalHostFunction · 0.70
processTemplateFunction · 0.70

Calls 2

getHostConfigFunction · 0.90

Tested by

no test coverage detected