import { FormatAdapter, GeneratorOptions, GeneratorResult, FormatName } from '@json-to-office/jto-ops'; export { DocxFormatAdapter, FontStageHandle, FontStageOptions, FontStager, FontconfigStager, FormatAdapter, FormatName, GeneratorOptions, GeneratorResult, MacOSCoreTextStager, NoopFontStager, PptxFormatAdapter, RasterizerCacheStats, WindowsFontStager, clearRasterizerCache, createAdapter, createLibreOfficePptxBatchRasterizer, createLibreOfficePptxRasterizer, getFontStager, getRasterizerCacheStats } from '@json-to-office/jto-ops'; import * as _sinclair_typebox from '@sinclair/typebox'; import { TSchema, Static } from '@sinclair/typebox'; import { EventEmitter } from 'events'; import { Command } from 'commander'; type ComponentDefinition = any; declare class GeneratorFactory { private registry; private adapter; constructor(adapter: FormatAdapter); createGenerator(options?: GeneratorOptions): Promise; generate(document: ComponentDefinition | string, options?: GeneratorOptions): Promise; /** The registered components, for quality preparation to expand. */ getPlugins(): readonly any[]; getPluginInfo(): { hasPlugins: boolean; count: number; names: string[]; }; } interface CustomComponent { name: string; versions?: Record; [key: string]: any; } declare class PluginLoader { private tsxUnregister?; initialize(): Promise; loadPlugin(filePath: string): Promise; loadPlugins(filePaths: string[]): Promise>; private extractComponent; private isValidComponent; cleanup(): void; } interface PluginExample { title?: string; props: any; description?: string; } interface PluginMetadata { name: string; description?: string; version?: string; format?: 'docx' | 'pptx'; filePath: string; relativePath: string; location: 'upstream' | 'downstream' | 'current'; hasChildren?: boolean; schema: { raw: TSchema; jsonSchema?: any; properties?: Record; }; examples?: PluginExample[]; } declare class PluginMetadataExtractor { private cwd; constructor(cwd?: string); extract(component: CustomComponent, filePath: string): Promise; private determineLocation; private detectFormat; private typeboxToJsonSchema; private extractProperties; private extractExamples; extractBatch(components: Map): Promise; } declare class PluginRegistry { private static instance; private plugins; private pluginPaths; private pluginMetadata; private loader; private discoveryService; private _format?; /** * Identity of the last successfully loaded plugin set (names + paths + * mtimes + sizes). A repeat load of an identical set is skipped entirely — * the playground fires `/load-plugins` many times around page load, and * each used to re-import every plugin and clear every cache, resetting * cache stats before they could mean anything (#156). */ private lastLoadFingerprint; private discoverAndLoadInFlight; private constructor(); static getInstance(): PluginRegistry; setFormat(format: 'docx' | 'pptx'): void; private notifyCacheInvalidation; loadPlugin(pathOrName: string): Promise; loadPlugins(pathsOrNames: string[]): Promise; /** * Fingerprint a discovered plugin set by content identity: name, path, * mtime, size. Metadata alone can't tell an edited file from an unchanged * one, and re-importing is exactly what must be skipped for unchanged sets. */ private computeLoadFingerprint; private loadPluginsFromMetadata; loadPluginsFromDirectory(dir: string): Promise; /** * Concurrent callers coalesce into one discovery pass: the playground's * bootstrap POST /load-plugins and on-demand schema-generation loads race * on page load, and each used to run its own discovery walk and re-import * every plugin. */ discoverAndLoad(): Promise<{ discovered: number; loaded: number; }>; private performDiscoverAndLoad; resolvePluginName(name: string): Promise; private resolvePluginPath; getPlugins(): CustomComponent[]; getPluginNames(): string[]; getPlugin(name: string): CustomComponent | undefined; hasPlugins(): boolean; getPluginCount(): number; clear(): void; static cleanup(): void; getPluginMetadata(name: string): PluginMetadata | undefined; getAllPluginMetadata(): PluginMetadata[]; } declare class PluginResolver { private discoveryService; private discoveredPlugins; private lastDiscoveryTime; private readonly CACHE_DURATION; private format?; constructor(format?: 'docx' | 'pptx'); resolve(input: string): Promise; resolveMultiple(inputs: string[]): Promise>; private resolveAsPath; private resolveAsName; private refreshDiscoveryCache; private isCacheExpired; private looksLikePath; private createNotFoundError; private findSimilarNames; getAvailablePluginNames(): Promise; clearCache(): void; } type DiscoveryType = 'plugin' | 'docx-document' | 'pptx-document' | 'pptx-theme' | 'docx-theme'; interface DiscoverOptions { scope?: string; maxDepth?: number; includeNodeModules?: boolean; verbose?: boolean; type?: DiscoveryType | 'all'; } interface DocumentMetadata { name: string; path: string; location: 'current' | 'downstream'; type?: string; title?: string; description?: string; theme?: string; } interface ThemeMetadata { name: string; path: string; location: 'current' | 'downstream'; description?: string; } declare class PluginDiscoveryService { private scanner; private loader; private metadataExtractor; private options; private searchPath; private projectRoot; constructor(options?: DiscoverOptions); discover(format?: 'docx' | 'pptx'): Promise; discoverPlugins(format?: 'docx' | 'pptx'): Promise; discoverDocuments(format?: 'docx' | 'pptx'): Promise; discoverThemes(format: 'docx' | 'pptx'): Promise; getDocumentContent(name: string, format?: 'docx' | 'pptx'): Promise; getThemeContent(name: string, format: 'docx' | 'pptx'): Promise; discoverAll(format: 'docx' | 'pptx'): Promise<{ plugins: PluginMetadata[]; documents: DocumentMetadata[]; themes: ThemeMetadata[]; }>; private getFileLocation; private searchDownstream; hasPlugins(): Promise; getPluginByName(name: string): Promise; } interface SchemaGenerateOptions { includeDocument?: boolean; includeTheme?: boolean; split?: boolean; format?: 'json' | 'typebox'; } interface SchemaGenerateResults { document?: string; theme?: string; components?: string[]; } declare class SchemaGenerator { private registry; private typeboxExporter; private formatName; constructor(formatName?: FormatName); generateAndExportSchemas(outputDir: string, options?: SchemaGenerateOptions): Promise; private generateDocumentSchema; private generateThemeSchema; private generateComponentSchemas; private getStandardComponentSchemas; private getCustomComponents; } interface ValidationError { path: string; message: string; code?: string; severity?: 'error' | 'warning' | 'info'; line?: number; column?: number; suggestion?: string; value?: any; source?: string; ruleId?: string; category?: string; certainty?: string; relatedPaths?: readonly string[]; evidence?: unknown; fixes?: readonly unknown[]; } interface ValidateFileResult { file: string; valid: boolean; type?: 'document' | 'theme' | 'custom'; errors?: ValidationError[]; warnings?: ValidationError[]; } interface ValidateOptions { type?: 'document' | 'theme' | 'auto'; schema?: string; strict?: boolean; recursive?: boolean; quality?: GeneratorOptions['quality']; } declare class JsonValidator { private format; private adapter?; constructor(format?: FormatName, adapter?: FormatAdapter); validate(pathOrPattern: string, options?: ValidateOptions): Promise; validateFile(filePath: string, options?: ValidateOptions): Promise; private validateAsDocument; private validateAsTheme; private validateWithCustomSchema; private detectType; private getFilesToValidate; formatError(error: ValidationError, indent?: number): string; formatResultsAsJson(results: ValidateFileResult[]): string; } interface CacheEvents { 'cache:invalidate': () => void; 'schema:invalidate': () => void; 'generator:invalidate': () => void; } declare class CacheEventEmitter extends EventEmitter { emit(event: K, ...args: Parameters): boolean; on(event: K, listener: CacheEvents[K]): this; off(event: K, listener: CacheEvents[K]): this; once(event: K, listener: CacheEvents[K]): this; } declare const cacheEvents: CacheEventEmitter; declare function invalidateAllCaches(): void; interface PluginConfig { plugins?: string[]; pluginDirs?: string[]; autoDiscover?: boolean; aliases?: Record; theme?: string | any; themePath?: string; discovery?: { maxDepth?: number; includeNodeModules?: boolean; upstreamOnly?: boolean; downstreamOnly?: boolean; }; validation?: { strict?: boolean; allowUnknownFields?: boolean; }; } declare class PluginConfigService { private static instance; private config; private configPath; private static readonly CONFIG_FILES; private constructor(); static getInstance(): PluginConfigService; loadConfig(startPath?: string): Promise; private loadFromPackageJson; getConfig(): PluginConfig | null; getConfigPath(): string | null; /** * `theme` and `themePath` are two spellings of one decision, and `themePath` * is the one resolved first — so merging them key-by-key would let a * config-file `themePath` outrank an explicit `--theme`. They merge as a * group instead: either flag supersedes both config-file keys, and with * neither flag the config file keeps both. This method is the only place * that sees CLI and config-file origins side by side, so precedence between * the two is settled here rather than downstream. */ private mergeThemeSelection; mergeWithOptions(options: Partial): PluginConfig; private mergeArrays; resolveAlias(name: string): string; getConfiguredPlugins(): string[]; getPluginDirectories(): string[]; isAutoDiscoverEnabled(): boolean; saveConfig(config: PluginConfig, filePath?: string): Promise; createDefaultConfig(filePath?: string): Promise; clearConfig(): void; } /** * Dev-server config file. Every key here is read by the dev server — inert * keys (playground flags, api.*, paths.*, server.cors, development.hmr / * sourceMap / verbose) were removed rather than left to imply an effect they * never had. Unknown keys still validate, so older config files keep loading. */ declare const ConfigSchema: _sinclair_typebox.TObject<{ mode: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"development">, _sinclair_typebox.TLiteral<"production">]>; server: _sinclair_typebox.TObject<{ port: _sinclair_typebox.TNumber; host: _sinclair_typebox.TString; }>; development: _sinclair_typebox.TObject<{ hmrPort: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>; }>; }>; type Config = Static; /** * Strict: the whole string must be a port. `Number.parseInt` stops at the * first non-digit, so it would read "8080x" — or "3003; rm -rf" — as 8080. */ declare function parsePort(value: string | undefined): number | undefined; interface LoadConfigOptions { /** * Port used when neither the config file nor `PORT` names one — lets a * caller supply its own default (e.g. the format's port) without the loader * having to guess which of the returned values was actually requested. */ defaultPort?: number; } declare function loadConfig(configPath?: string, options?: LoadConfigOptions): Promise; interface RegisterOptions { /** * Extra per-format commands to mount alongside the core set. * Full `jto` uses this to inject the `dev` playground command without * forcing the lean CLI to depend on playground code. */ extraCommands?: (adapter: FormatAdapter) => Command[]; } /** * Attach the format-scoped `docx` and `pptx` subcommands (with all core CLI * commands) to a commander program. Callers wire their own name/version/help. */ declare function registerCoreCommands(program: Command, options?: RegisterOptions): Command; declare const EXIT_CODES: { readonly OK: 0; readonly FAIL: 1; }; type UiTone = 'default' | 'info' | 'success' | 'warning' | 'error' | 'muted'; interface UiLine { text: string; tone?: UiTone; } interface TaskReporter { update(message: string): void; log(message: string, tone?: UiTone): void; } declare function runTask(initial: string, task: (reporter: TaskReporter) => Promise, options?: { success?: string | ((value: T) => string); failure?: string; stdout?: NodeJS.WriteStream; }): Promise; declare function renderLines(lines: UiLine[], stdout?: NodeJS.WriteStream): Promise; declare function promptText(label: string, initial: string): Promise; declare function shortPath(absPath: string): string; declare function dimPath(absPath: string): string; /** Dependency-free table formatter; Ink handles final rendering. */ declare function createTable(headers: string[], rows: string[][]): string; declare function formatTiming(startMs: number): string; /** Failures belong on stderr so `cmd > out.json` keeps data and errors apart. */ declare function formatError(error: unknown): Promise; export { type Config, type CustomComponent, type DiscoverOptions, type DocumentMetadata, EXIT_CODES, GeneratorFactory, JsonValidator, type PluginConfig, PluginConfigService, PluginDiscoveryService, type PluginExample, PluginLoader, type PluginMetadata, PluginMetadataExtractor, PluginRegistry, PluginResolver, type SchemaGenerateOptions, type SchemaGenerateResults, SchemaGenerator, type TaskReporter, type ThemeMetadata, type UiLine, type UiTone, type ValidateFileResult, type ValidateOptions, type ValidationError, cacheEvents, createTable, dimPath, formatError, formatTiming, invalidateAllCaches, loadConfig, parsePort, promptText, registerCoreCommands, renderLines, runTask, shortPath };