Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Data Audit

on:
pull_request:
paths:
- 'src/docs.json'
- 'tests/audit/**'
schedule:
- cron: '0 0 * * *' # Daily at midnight
workflow_dispatch:

jobs:
audit-links:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22.x
cache: npm
- name: Install dependencies
run: npm ci
- name: Run documentation audit
run: npm run test:audit
env:
# Higher limit for scheduled runs (0 = no limit), lower for PRs
DOCS_AUDIT_MAX_TOTAL: ${{ github.event_name == 'schedule' && '0' || '50' }}
# Advisories are non-blocking for PRs
continue-on-error: ${{ github.event_name == 'pull_request' }}
12 changes: 9 additions & 3 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,19 @@ export default {
},
{
displayName: 'e2e',
roots: ['tests'],
testMatch: ['<rootDir>/tests/**/*.test.ts'],
setupFilesAfterEnv: ['<rootDir>/tests/jest.setupTests.ts'],
roots: ['tests/e2e'],
testMatch: ['<rootDir>/tests/e2e/**/*.test.ts'],
setupFilesAfterEnv: ['<rootDir>/tests/e2e/jest.setupTests.ts'],
transformIgnorePatterns: [
'<rootDir>/dist/'
],
...baseConfig
},
{
displayName: 'audit',
roots: ['tests/audit'],
testMatch: ['<rootDir>/tests/audit/**/*.test.ts'],
...baseConfig
}
]
};
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"main": "dist/index.js",
"type": "module",
"imports": {
"~docsCatalog": "./src/docs.json",
"#toolsHost": "./dist/server.toolsHost.js"
},
"exports": {
Expand Down Expand Up @@ -32,8 +33,9 @@
"start": "node dist/cli.js --log-stderr",
"start:dev": "tsx watch src/cli.ts --verbose --log-stderr",
"test": "npm run test:spell && npm run test:spell-docs && npm run test:lint && npm run test:types && jest --selectProjects unit --roots=src/",
"test:audit": "jest --selectProjects audit --roots=tests/audit/",
"test:dev": "npm test -- --watchAll",
"test:integration": "npm run build && NODE_OPTIONS='--experimental-vm-modules' jest --selectProjects e2e --roots=tests/",
"test:integration": "npm run build && NODE_OPTIONS='--experimental-vm-modules' jest --selectProjects e2e --roots=tests/e2e/",
"test:integration-dev": "npm run test:integration -- --watchAll",
"test:lint": "eslint .",
"test:lint-fix": "eslint . --fix",
Expand Down
67 changes: 67 additions & 0 deletions src/__tests__/__snapshots__/docs.embedded.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing

exports[`EMBEDDED_DOCS should export the expected embedded docs structure: docs 1`] = `
{
"docs": {
"React": [
{
"category": "react",
"description": "Direct source for PatternFly React component examples.",
"displayName": "PatternFly React Docs",
"path": "https://raw.githubusercontent.com/patternfly/patternfly-react/refs/heads/main/README.md",
"pathSlug": "patternfly-react",
"section": "components",
"source": "github",
"version": "v6",
},
{
"category": "react",
"description": "AI guidance for PatternFly React development rules.",
"displayName": "React Development Rules",
"path": "https://raw.githubusercontent.com/patternfly/ai-helpers/refs/heads/main/docs/README.md",
"pathSlug": "react-development",
"section": "guidelines",
"source": "github",
"version": "v6",
},
],
"patternfly": [
{
"category": "reference",
"description": "Official PatternFly design system website.",
"displayName": "PatternFly Home",
"path": "https://www.patternfly.org",
"pathSlug": "patternfly-home",
"section": "home",
"source": "website",
"version": "v6",
},
{
"category": "reference",
"description": "PatternFly organization on GitHub (Core & React).",
"displayName": "PatternFly GitHub",
"path": "https://github.com/patternfly",
"pathSlug": "patternfly-github",
"section": "github",
"source": "github",
"version": "v6",
},
{
"category": "reference",
"description": "Direct source for PatternFly documentation and guidelines.",
"displayName": "PatternFly Org",
"path": "https://github.com/patternfly/patternfly-org",
"pathSlug": "patternfly-org",
"section": "github",
"source": "github",
"version": "v6",
},
],
},
"meta": {
"source": "patternfly-mcp-fallback",
"totalDocs": 5,
"totalEntries": 2,
},
}
`;
19 changes: 19 additions & 0 deletions src/__tests__/docs.embedded.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { EMBEDDED_DOCS } from '../docs.embedded';

describe('EMBEDDED_DOCS', () => {
it('should export the expected embedded docs structure', () => {
expect(EMBEDDED_DOCS).toMatchSnapshot('docs');
});

it('should contain valid high-level metadata and entry points', () => {
const { docs, meta } = EMBEDDED_DOCS;

expect(meta.source).toBe('patternfly-mcp-fallback');
expect(docs).toHaveProperty('patternfly');
expect(docs).toHaveProperty('React');

const allDocs = Object.values(docs).flat();

expect(allDocs.length).toBeGreaterThanOrEqual(5);
});
});
115 changes: 115 additions & 0 deletions src/docs.embedded.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/**
* PatternFly JSON catalog doc
*/
type PatternFlyMcpDocsCatalogDoc = {
displayName: string;
description: string;
pathSlug: string;
section: string;
category: string;
source: string;
path: string;
version: string;
};

/**
* PatternFly JSON catalog documentation entries.
*/
type PatternFlyMcpDocsCatalogEntry = {
[key: string]: PatternFlyMcpDocsCatalogDoc[]
};

/**
* PatternFly documentation catalog.
*
* @interface PatternFlyMcpDocsCatalog
*
* @property [version] - Version of the catalog.
* @property [generated] - Date when the catalog was generated.
* @property {PatternFlyMcpDocsCatalogEntry} docs - PatternFly documentation entries.
*/
interface PatternFlyMcpDocsCatalog {
version?: string;
generated?: string;
meta: {
totalEntries: number;
totalDocs: number;
source: string;
};
docs: PatternFlyMcpDocsCatalogEntry
}

/**
* Fallback documentation for when the catalog is unavailable.
* Points to the high-level entry points for PatternFly.
*/
const EMBEDDED_DOCS: PatternFlyMcpDocsCatalog = {
meta: {
totalEntries: 2,
totalDocs: 5,
source: 'patternfly-mcp-fallback'
},
docs: {
patternfly: [
{
displayName: 'PatternFly Home',
description: 'Official PatternFly design system website.',
pathSlug: 'patternfly-home',
section: 'home',
category: 'reference',
source: 'website',
path: 'https://www.patternfly.org',
version: 'v6'
},
{
displayName: 'PatternFly GitHub',
description: 'PatternFly organization on GitHub (Core & React).',
pathSlug: 'patternfly-github',
section: 'github',
category: 'reference',
source: 'github',
path: 'https://github.com/patternfly',
version: 'v6'
},
{
displayName: 'PatternFly Org',
description: 'Direct source for PatternFly documentation and guidelines.',
pathSlug: 'patternfly-org',
section: 'github',
category: 'reference',
source: 'github',
path: 'https://github.com/patternfly/patternfly-org',
version: 'v6'
}
],
React: [
{
displayName: 'PatternFly React Docs',
description: 'Direct source for PatternFly React component examples.',
pathSlug: 'patternfly-react',
section: 'components',
category: 'react',
source: 'github',
path: 'https://raw.githubusercontent.com/patternfly/patternfly-react/refs/heads/main/README.md',
version: 'v6'
},
{
displayName: 'React Development Rules',
description: 'AI guidance for PatternFly React development rules.',
pathSlug: 'react-development',
section: 'guidelines',
category: 'react',
source: 'github',
path: 'https://raw.githubusercontent.com/patternfly/ai-helpers/refs/heads/main/docs/README.md',
version: 'v6'
}
]
}
};

export {
EMBEDDED_DOCS,
type PatternFlyMcpDocsCatalog,
type PatternFlyMcpDocsCatalogEntry,
type PatternFlyMcpDocsCatalogDoc
};
Loading
Loading