fleet-memory/hindsight-docs/src/components/CodeSnippet.tsx
DK09876 8ecb5d3a0c
Add documentation code validation system (#43)
* Add documentation code validation system

- Create runnable example scripts in examples/api/ (19 files)
- Add CodeSnippet component for extracting marked sections
- Add raw-loader dependency for importing source files
- Create sample retain-new.mdx showing new approach
- Add README documenting coverage and gaps

* Fix wheel glob expansion in test-doc-examples CI job

* Fix CI issue

* Fix wheel path - uv build outputs to repo root dist/

* Fix: use explicit shell expansion for wheel install

* Fix: run cd in subshell so install runs from repo root

* Add documentation code validation CI job

- Use uv sync + uv run pattern (matches existing CI)
- Add requests to test dependencies for cleanup scripts

* Fix async API client usage in documents.py example

* Fix main-methods.py: RecallResult and ReflectFact don't have weight attribute

* Fix opinions.py: use actual API attributes instead of non-existent ones

* Fix example scripts: remove non-existent API attributes

- recall.py: remove .weight, fix entities iteration (dict not list)
- retain.mjs: remove result.async check
2025-12-18 10:21:38 +01:00

110 lines
2.9 KiB
TypeScript

import React from 'react';
import CodeBlock from '@theme/CodeBlock';
interface CodeSnippetProps {
/** Raw file content (use raw-loader to import) */
code: string;
/** Section marker name (e.g., "retain-basic" for [docs:retain-basic]) */
section: string;
/** Language for syntax highlighting */
language: string;
/** Optional title for the code block */
title?: string;
}
/**
* Extracts a marked section from source code.
*
* Markers are in the format:
* - Start: `# [docs:section-name]` (Python/Bash) or `// [docs:section-name]` (JS/TS)
* - End: `# [/docs:section-name]` (Python/Bash) or `// [/docs:section-name]` (JS/TS)
*/
function extractSection(code: string, section: string): string {
// Match both Python/Bash (#) and JS/TS (//) comment styles
const startPattern = new RegExp(`(?:#|//)\\s*\\[docs:${section}\\]`);
const endPattern = new RegExp(`(?:#|//)\\s*\\[/docs:${section}\\]`);
const lines = code.split('\n');
let inSection = false;
const sectionLines: string[] = [];
for (const line of lines) {
if (startPattern.test(line)) {
inSection = true;
continue;
}
if (endPattern.test(line)) {
inSection = false;
continue;
}
if (inSection) {
sectionLines.push(line);
}
}
if (sectionLines.length === 0) {
console.warn(`CodeSnippet: Section "${section}" not found in code`);
return `// Section "${section}" not found`;
}
// Trim leading/trailing empty lines and normalize indentation
return trimAndNormalize(sectionLines);
}
/**
* Trims leading/trailing empty lines and removes common leading indentation.
*/
function trimAndNormalize(lines: string[]): string {
// Remove leading empty lines
while (lines.length > 0 && lines[0].trim() === '') {
lines.shift();
}
// Remove trailing empty lines
while (lines.length > 0 && lines[lines.length - 1].trim() === '') {
lines.pop();
}
if (lines.length === 0) return '';
// Find minimum indentation (ignoring empty lines)
const nonEmptyLines = lines.filter(l => l.trim() !== '');
if (nonEmptyLines.length === 0) return '';
const minIndent = Math.min(
...nonEmptyLines.map(line => {
const match = line.match(/^(\s*)/);
return match ? match[1].length : 0;
})
);
// Remove common indentation
return lines
.map(line => line.slice(minIndent))
.join('\n');
}
/**
* CodeSnippet component for embedding code from example files.
*
* Usage in MDX:
* ```mdx
* import CodeSnippet from '@site/src/components/CodeSnippet';
* import retainPy from '!!raw-loader!@site/examples/api/retain.py';
*
* <CodeSnippet code={retainPy} section="retain-basic" language="python" />
* ```
*/
export default function CodeSnippet({
code,
section,
language,
title
}: CodeSnippetProps): React.ReactElement {
const extractedCode = extractSection(code, section);
return (
<CodeBlock language={language} title={title}>
{extractedCode}
</CodeBlock>
);
}