Scan
Functions
parseSourceArgs
function parseSourceArgs(args: string[]): SourceEntry[]
Use parseSourceArgs to convert raw CLI source arguments into structured path entries that skrypt's scanner can process.
Reach for this when you're building a custom CLI wrapper around skrypt's generation pipeline and need to accept source paths from user input — with or without human-readable labels attached.
Each argument is split on the last colon to separate the filesystem path from an optional display label (e.g. "./api:Public API"). Arguments without a colon are returned with only a path. The colon-detection logic intentionally ignores Windows drive letters like C:\.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
args | string[] | Yes | Raw source path arguments, each optionally suffixed with :<label> to control how that source appears in generated docs. Paths can be relative or absolute. |
Returns
Returns an array of SourceEntry objects, each with a path and an optional label. Pass this array directly to skrypt's scanner or config resolver to kick off documentation generation for the specified sources.
Heads up
- The split happens on the last colon in the string, so paths like
./src/http:client:HTTP Clientwill useHTTP Clientas the label and./src/http:clientas the path. Keep labels simple to avoid ambiguity. - Relative paths are preserved as-is — resolution against the working directory happens downstream, not here.
Example:
type SourceEntry = {
path: string;
label?: string;
};
function parseSourceArgs(args: string[]): SourceEntry[] {
return args.map(arg => {
const colonIdx = arg.lastIndexOf(':');
if (colonIdx > 1 && !arg.substring(0, colonIdx).endsWith('\\')) {
return {
path: arg.substring(0, colonIdx),
label: arg.substring(colonIdx + 1),
};
}
return { path: arg };
});
}
// Simulates: skrypt generate ./src ./api:Public API ./internal:Internal
const rawArgs = ['./src', './api:Public API', './internal:Internal'];
try {
const entries = parseSourceArgs(rawArgs);
console.log(entries);
// [
// { path: './src' },
// { path: './api', label: 'Public API' },
// { path: './internal', label: 'Internal' }
// ]
} catch (err) {
console.error('Failed to parse source args:', err);
}
readIgnorePatterns
function readIgnorePatterns(sourcePath: string): string[]
Use readIgnorePatterns to load the exclusion rules that tell skrypt generate which files and symbols to skip during documentation generation.
Call this before scanning a source directory when you need to inspect or extend the active ignore rules — for example, to merge project-level patterns with additional runtime exclusions before passing them to the scanner.
skrypt looks for a .skryptignore file at the root of your source directory. Each non-empty line in that file becomes a glob pattern. If no .skryptignore exists, the function returns an empty array and scanning proceeds without exclusions.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
sourcePath | string | Yes | Absolute or relative path to the source directory to scan — the function looks for .skryptignore directly inside this directory, not in parent folders |
Returns
An array of glob pattern strings parsed from .skryptignore, one entry per non-empty line. Returns [] if no ignore file is found. Pass the result to your scanner configuration to filter out matched paths before documentation is generated.
Heads up
- Patterns are read from
<sourcePath>/.skryptignoreonly — a.skryptignorein a parent or nested directory is silently ignored. - The function returns raw lines from the file without validation; malformed glob patterns won't throw but will silently fail to match anything during scanning.
Example:
import { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync } from 'fs'
import { join } from 'path'
import { tmpdir } from 'os'
// Inline implementation — do not import from autodocs
function readIgnorePatterns(sourcePath: string): string[] {
const ignorePath = join(sourcePath, '.skryptignore')
if (!existsSync(ignorePath)) return []
const content = readFileSync(ignorePath, 'utf-8')
return content
.split('\n')
.map((line) => line.trim())
.filter((line) => line.length > 0 && !line.startsWith('#'))
}
// Set up a temporary source directory with a .skryptignore file
const sourceDir = join(tmpdir(), 'my-project-src')
mkdirSync(sourceDir, { recursive: true })
writeFileSync(
join(sourceDir, '.skryptignore'),
[
'# Ignore generated and test files',
'dist/**',
'**/*.test.ts',
'**/__mocks__/**',
'src/internal/**',
].join('\n')
)
try {
const patterns = readIgnorePatterns(sourceDir)
console.log('Active ignore patterns:', patterns)
// Active ignore patterns: [ 'dist/**', '**/*.test.ts', '**/__mocks__/**', 'src/internal/**' ]
// Merge with any runtime exclusions before passing to the scanner
const runtimeExclusions = ['**/generated/**']
const allPatterns = [...patterns, ...runtimeExclusions]
console.log('Merged patterns for scanner:', allPatterns)
// Check behavior when no .skryptignore exists
const emptyDir = join(tmpdir(), 'project-no-ignore')
mkdirSync(emptyDir, { recursive: true })
console.log('No ignore file present:', readIgnorePatterns(emptyDir))
// No ignore file present: []
rmSync(emptyDir, { recursive: true })
} catch (err) {
console.error('Failed to read ignore patterns:', err)
} finally {
rmSync(sourceDir, { recursive: true })
}
findOpenAPISpec
function findOpenAPISpec(sourcePath: string): string | null
Use findOpenAPISpec to automatically locate an OpenAPI or Swagger spec file in your project directory without hardcoding its path.
Reach for this when you're building a doc generation pipeline and want to support projects that may use any of the common OpenAPI filename conventions (openapi.json, openapi.yaml, swagger.json, etc.) without requiring the user to specify the file explicitly.
The function scans a fixed list of candidate filenames in the given directory and returns the absolute path to the first one it finds on disk.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
sourcePath | string | Yes | Path to the directory to search — typically your project's src or root folder. Relative paths are resolved from the current working directory. |
Returns
The absolute path to the detected spec file as a string, or null if none of the known candidates exist in the directory. When you get a path back, pass it directly to your spec parser or include it in your skrypt generate config to drive REST API doc generation alongside your code docs.
Heads up
- Only the directory itself is searched — subdirectories are not traversed. If your spec lives at
src/api/openapi.yaml, passsrc/apias thesourcePath, notsrc. - Returns the first match found, so if you have both
openapi.jsonandopenapi.yamlpresent, the result depends on the internal candidate order rather than which file is newer or more complete.
Example:
import { existsSync } from 'fs'
import { resolve, join } from 'path'
function findOpenAPISpec(sourcePath: string): string | null {
const candidates = [
'openapi.json',
'openapi.yaml',
'openapi.yml',
'swagger.json',
'swagger.yaml',
'swagger.yml',
]
for (const candidate of candidates) {
const fullPath = join(resolve(sourcePath), candidate)
if (existsSync(fullPath)) {
return fullPath
}
}
return null
}
// Simulate a project directory that contains openapi.yaml
const projectSrcPath = './my-project/src'
const specPath = findOpenAPISpec(projectSrcPath)
if (specPath) {
console.log(`Found OpenAPI spec: ${specPath}`)
// => Found OpenAPI spec: /home/user/my-project/src/openapi.yaml
// Pass specPath to your doc generator or spec parser next
} else {
console.log('No OpenAPI spec found — skipping REST API doc generation')
}
shouldExcludeElement
function shouldExcludeElement(element: APIElement, patterns: string[]): boolean
Use shouldExcludeElement to filter API elements out of your generated documentation based on name or pattern rules.
Reach for this when building a custom generation pipeline and you need to programmatically decide whether a scanned element should appear in the output — for example, skipping internal helpers, deprecated symbols, or anything prefixed with _.
Each pattern in the array is evaluated against the element in order. A pattern prefixed with name: matches the element's exact name (e.g., name:_internalHelper). The function returns true on the first match, so order your patterns from most specific to least.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
element | APIElement | Yes | The scanned API element to evaluate — includes its name, kind, file path, and signature. |
patterns | string[] | Yes | Exclusion rules to test against the element. Prefix with name: to match by exact name. An empty array always returns false. |
Returns
Returns true if the element matches any pattern and should be dropped from the output, false if it should be included. Use the return value to filter your elements array before passing it to the doc generator.
Heads up
- Matching is exact when using
name:—name:createUserwon't matchcreateUserFromEmail. Use multiple patterns if you need to exclude a family of names. - Passing an empty
patternsarray is safe and always returnsfalse, so all elements pass through.
Example:
type APIElementKind = "function" | "class" | "interface" | "type" | "variable";
interface APIElement {
name: string;
kind: APIElementKind;
filePath: string;
signature: string;
docstring?: string;
}
function shouldExcludeElement(element: APIElement, patterns: string[]): boolean {
for (const pattern of patterns) {
if (pattern.startsWith("name:")) {
const namePattern = pattern.slice(5);
if (element.name === namePattern) {
return true;
}
}
}
return false;
}
const scannedElements: APIElement[] = [
{
name: "createPayment",
kind: "function",
filePath: "src/payments/index.ts",
signature: "function createPayment(amount: number, currency: string): Promise<Payment>",
docstring: "Creates a new payment intent.",
},
{
name: "_resolveInternalConfig",
kind: "function",
filePath: "src/payments/internal.ts",
signature: "function _resolveInternalConfig(): Config",
},
{
name: "legacyChargeCard",
kind: "function",
filePath: "src/payments/legacy.ts",
signature: "function legacyChargeCard(token: string): void",
docstring: "Deprecated. Use createPayment instead.",
},
];
const excludePatterns = [
"name:_resolveInternalConfig",
"name:legacyChargeCard",
];
try {
const publicElements = scannedElements.filter(
(el) => !shouldExcludeElement(el, excludePatterns)
);
console.log("Elements included in docs:");
publicElements.forEach((el) => console.log(` - ${el.name} (${el.kind})`));
// Elements included in docs:
// - createPayment (function)
} catch (err) {
console.error("Failed to filter elements:", err);
}
scanSources
async function scanSources(sources: string[], options: ScanOptions, config: Config): Promise<ScanResult>
Use scanSources to scan one or more source directories and get back a unified list of API elements ready for documentation generation.
This is the core orchestration step in a skrypt generate pipeline — call it after you've resolved your configuration but before you pass elements to the AI doc generator. It handles the full sweep: resolving which directories to scan, applying language and filter rules, and returning a flat, normalized collection of extracted API signatures.
Under the hood, scanSources merges sources from three possible origins — CLI arguments, an --org flag, or your config file — then applies your filter options and walks each directory recursively to extract typed API elements.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
sources | string[] | Yes | Paths to the source directories or files to scan. Pass an empty array to fall back to sources defined in config. |
options | ScanOptions | Yes | Controls what gets extracted — language filters, glob patterns to exclude, and whether to scan recursively. |
config | Config | Yes | Your resolved skrypt config object. Used as the fallback source list and carries provider/output settings downstream. |
Returns
Returns a Promise<ScanResult> containing the full list of extracted APIElement objects and metadata about the scan (files visited, elements found, any parse errors). Pass result.elements directly to your doc generation step to produce MDX output.
Heads up
- If you pass both
sourcesand have sources defined inconfig, the CLIsourcesarray takes precedence — config sources are only used whensourcesis empty. - Parse errors in individual files are collected into
result.errorsrather than thrown, so always check that field before assuming the element list is complete.
Example:
import { promises as fs } from "fs";
import * as path from "path";
// --- Inline types (do not import from autodocs) ---
interface ScanOptions {
languages?: string[];
exclude?: string[];
recursive?: boolean;
byTopic?: boolean;
}
interface Config {
output: string;
provider: string;
sources?: string[];
}
interface APIElement {
name: string;
kind: "function" | "class" | "type" | "constant";
signature: string;
filePath: string;
language: string;
docstring?: string;
}
interface ScanResult {
elements: APIElement[];
filesVisited: number;
errors: Array<{ file: string; message: string }>;
}
// --- Mock implementation of scanSources ---
async function scanSources(
sources: string[],
options: ScanOptions,
config: Config
): Promise<ScanResult> {
const resolvedSources = sources.length > 0 ? sources : (config.sources ?? []);
// Simulate scanning — in production this walks the FS and parses ASTs
const mockElements: APIElement[] = resolvedSources.flatMap((src) => [
{
name: "createPayment",
kind: "function",
signature: "async function createPayment(amount: number, currency: string): Promise<Payment>",
filePath: path.join(src, "payments.ts"),
language: "typescript",
docstring: "Creates a new payment intent and returns the client secret.",
},
{
name: "PaymentClient",
kind: "class",
signature: "class PaymentClient { constructor(apiKey: string) }",
filePath: path.join(src, "client.ts"),
language: "typescript",
},
]);
const filtered = mockElements.filter((el) =>
options.languages ? options.languages.includes(el.language) : true
);
return {
elements: filtered,
filesVisited: resolvedSources.length * 4,
errors: [],
};
}
// --- Usage ---
async function main() {
const config: Config = {
output: "./docs/content",
provider: "openai",
sources: ["./src/core"],
};
const options: ScanOptions = {
languages: ["typescript"],
exclude: ["**/*.test.ts", "**/node_modules/**"],
recursive: true,
};
try {
const result = await scanSources(["./src/payments", "./src/auth"], options, config);
if (result.errors.length > 0) {
console.warn("Parse errors encountered:", result.errors);
}
console.log(`Scanned ${result.filesVisited} files, found ${result.elements.length} API elements`);
// → Scanned 8 files, found 4 API elements
console.log("Elements ready for doc generation:");
result.elements.forEach((el) => {
console.log(` [${el.kind}] ${el.name} — ${el.filePath}`);
});
// → [function] createPayment — ./src/payments/payments.ts
// → [class] PaymentClient — ./src/payments/client.ts
// → [function] createPayment — ./src/auth/payments.ts
// → [class] PaymentClient — ./src/auth/client.ts
} catch (err) {
console.error("Scan failed:", err);
process.exit(1);
}
}
main();