peam 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ import { SearchExporterConfig } from '@peam-ai/search';
2
+
3
+ /**
4
+ * Peam Static Site Indexer
5
+ *
6
+ * Scans a static site output directory, discovers HTML files,
7
+ * parses them into structured pages, and creates a searchable index.
8
+ */
9
+
10
+ interface IndexerConfig {
11
+ source: string;
12
+ searchExporter: SearchExporterConfig;
13
+ respectRobotsTxt: boolean;
14
+ robotsTxtPath?: string;
15
+ exclude: string[];
16
+ glob: string;
17
+ projectDir: string;
18
+ }
19
+ declare function indexPages(config: IndexerConfig): Promise<void>;
20
+
21
+ export { type IndexerConfig, indexPages };
package/dist/cli.js CHANGED
@@ -24,6 +24,27 @@ var packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, "../package.js
24
24
  function parseExcludePatterns(value) {
25
25
  return value.split(",").map((p) => p.trim()).filter(Boolean);
26
26
  }
27
+ function parseExporterConfigEntry(value, previous = []) {
28
+ return [...previous, value];
29
+ }
30
+ function parseExporterConfig(options, exporterType) {
31
+ const exporterConfig = {};
32
+ if (Array.isArray(options.exporterConfig)) {
33
+ for (const entry of options.exporterConfig) {
34
+ if (typeof entry === "string") {
35
+ const [key, ...valueParts] = entry.split("=");
36
+ const value = valueParts.join("=");
37
+ if (key && value !== void 0) {
38
+ exporterConfig[key.trim()] = value.trim();
39
+ }
40
+ }
41
+ }
42
+ }
43
+ return {
44
+ type: exporterType,
45
+ config: exporterConfig
46
+ };
47
+ }
27
48
  var log = {
28
49
  success: (message) => console.log(chalk__default.default.green("\u2713 ") + message),
29
50
  error: (message) => console.error(chalk__default.default.red("\u2717 ") + message),
@@ -69,8 +90,8 @@ async function indexPages(config) {
69
90
  log.text(` Project Directory: ${log.gray(config.projectDir)}`);
70
91
  log.text(` Source Directory: ${log.gray(config.source)}`);
71
92
  log.text(` Glob Pattern: ${log.gray(config.glob)}`);
72
- log.text(` Output Directory: ${log.gray(config.outputDir)}`);
73
- log.text(` Index Filename: ${log.gray(config.indexFilename)}`);
93
+ log.text(` Exporter Type: ${log.gray(config.searchExporter.type)}`);
94
+ log.text(` Exporter Config: ${log.gray(JSON.stringify(config.searchExporter.config, null, 2))}`);
74
95
  log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);
75
96
  if (config.exclude.length > 0) {
76
97
  log.text(` Exclude Patterns: ${log.gray(config.exclude.join(", "))}`);
@@ -152,19 +173,10 @@ async function indexPages(config) {
152
173
  log.text("");
153
174
  log.text(log.bold("Saving index..."));
154
175
  log.text("");
155
- const outputPath = path.join(config.projectDir, config.outputDir);
156
- fs.mkdirSync(outputPath, { recursive: true });
157
- const generatedPath = path.join(outputPath, "generated");
158
- fs.mkdirSync(generatedPath, { recursive: true });
159
- const searchIndexFile = path.join(generatedPath, config.indexFilename);
160
- fs.writeFileSync(searchIndexFile, JSON.stringify(searchIndexData));
161
- const indexJsContent = `// Auto-generated by Peam - DO NOT EDIT THIS FILE
162
- import index from "./generated/${config.indexFilename}";
163
- export default index;
164
- `;
165
- const indexJsFile = path.join(outputPath, "index.js");
166
- fs.writeFileSync(indexJsFile, indexJsContent);
167
- log.success(`Index saved to: ${log.cyan(path.relative(config.projectDir, searchIndexFile))}`);
176
+ const searchIndexExporter = search.createExporterFromConfig(config.searchExporter);
177
+ await searchIndexExporter.export(searchIndexData);
178
+ const indexPathDisplay = config.searchExporter.type === "fileBased" ? path.relative(config.projectDir, path.join(config.projectDir, config.searchExporter.config.indexPath)) : "configured location";
179
+ log.success(`Index saved to: ${log.cyan(indexPathDisplay)}`);
168
180
  log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);
169
181
  log.text(
170
182
  ` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), "utf8") / 1024).toFixed(2))} KB`
@@ -185,7 +197,10 @@ function probeSourceDirectory(projectDir) {
185
197
  }
186
198
  async function main() {
187
199
  const program = new commander.Command();
188
- program.name("peam").description("Peam static site indexer (Next.js, Hugo, etc.)").version(packageJson.version).option("--source <path>", "Source directory containing HTML files (auto-detected if not provided)").option("--glob <pattern>", "Glob pattern for HTML files", "**/*.{html,htm}").option("--output-dir <path>", "Output directory for index", ".peam").option("--index-filename <name>", "Name of index file", "index.json").option("--ignore-robots-txt", "Disable robots.txt checking").option("--robots-path <path>", "Custom path to robots.txt file").option("--exclude <patterns>", "Comma-separated exclude patterns", parseExcludePatterns, []).option("--project-dir <path>", "Project root directory", process.cwd()).addHelpText(
200
+ program.name("peam").description("Peam static site indexer (Next.js, Hugo, etc.)").version(packageJson.version).option("--source <path>", "Source directory containing HTML files (auto-detected if not provided)").option("--glob <pattern>", "Glob pattern for HTML files", "**/*.{html,htm}").option("--exporter <type>", "Search exporter type", "fileBased").option("--exporterConfig <key=value>", "Exporter config entry (repeatable)", parseExporterConfigEntry, [
201
+ `baseDir=${process.cwd()}`,
202
+ "indexPath=.peam/index.json"
203
+ ]).option("--ignore-robots-txt", "Disable robots.txt checking").option("--robots-path <path>", "Custom path to robots.txt file").option("--exclude <patterns>", "Comma-separated exclude patterns", parseExcludePatterns, []).option("--project-dir <path>", "Project root directory", process.cwd()).addHelpText(
189
204
  "after",
190
205
  `
191
206
  Examples:
@@ -198,8 +213,11 @@ Examples:
198
213
  # Next.js
199
214
  $ peam --source .next
200
215
 
201
- # Custom output directory
202
- $ peam --source dist --glob "**/*.html"
216
+ # Custom index path using file-based exporter
217
+ $ peam --source dist --exporterConfig indexPath=.search/index.json
218
+
219
+ # Multiple exporter config entries
220
+ $ peam --exporterConfig indexPath=custom/index.json --exporterConfig baseDir=/tmp
203
221
 
204
222
  # Exclude patterns
205
223
  $ peam --exclude "/admin/**,/api/*,/private-*"
@@ -225,11 +243,11 @@ More information: https://peam.ai
225
243
  process.exit(1);
226
244
  }
227
245
  }
246
+ const searchExporter = parseExporterConfig(options, options.exporter);
228
247
  const config = {
229
248
  source: sourceDir,
230
249
  glob: options.glob,
231
- outputDir: options.outputDir,
232
- indexFilename: options.indexFilename,
250
+ searchExporter,
233
251
  respectRobotsTxt: !options.ignoreRobotsTxt,
234
252
  robotsTxtPath: options.robotsPath,
235
253
  exclude: options.exclude,
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"names":["readFileSync","join","chalk","fg","relative","filePathToPathname","existsSync","loadRobotsTxt","shouldIncludePath","parseHTML","buildSearchIndex","mkdirSync","writeFileSync","Command"],"mappings":"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","file":"cli.js","sourcesContent":["/**\n * Peam Static Site Indexer\n *\n * Scans a static site output directory, discovers HTML files,\n * parses them into structured pages, and creates a searchable index.\n */\n\nimport { filePathToPathname, loadRobotsTxt, parseHTML, shouldIncludePath, type StructuredPage } from '@peam-ai/parser';\nimport { buildSearchIndex } from '@peam-ai/search';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport fg from 'fast-glob';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { join, relative } from 'path';\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\ninterface IndexerConfig {\n source: string;\n outputDir: string;\n indexFilename: string;\n respectRobotsTxt: boolean;\n robotsTxtPath?: string;\n exclude: string[];\n glob: string;\n projectDir: string;\n}\n\ninterface DiscoveredPage {\n pathname: string;\n htmlFilePath: string;\n relativeHtmlPath: string;\n}\n\nfunction parseExcludePatterns(value: string): string[] {\n return value\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n}\n\nconst log = {\n success: (message: string) => console.log(chalk.green('✓ ') + message),\n error: (message: string) => console.error(chalk.red('✗ ') + message),\n warn: (message: string) => console.warn(chalk.yellow('⚠ ') + message),\n info: (message: string) => console.log(chalk.blue('ℹ ') + message),\n text: (message: string) => console.log(message),\n\n cyan: (text: string) => chalk.cyan(text),\n gray: (text: string) => chalk.gray(text),\n bold: (text: string) => chalk.bold(text),\n yellow: (text: string) => chalk.yellow(text),\n red: (text: string) => chalk.red(text),\n green: (text: string) => chalk.green(text),\n};\n\nasync function discoverHtmlFiles(\n sourceDir: string,\n globPattern: string,\n projectDir: string\n): Promise<DiscoveredPage[]> {\n const pages: DiscoveredPage[] = [];\n\n try {\n const sourceFullPath = join(projectDir, sourceDir);\n\n const htmlFiles = await fg(globPattern, {\n cwd: sourceFullPath,\n absolute: true,\n onlyFiles: true,\n dot: false,\n ignore: ['**/_next/**', '**/_astro/**', '**/404.{html,htm}', '**/500.{html,htm}'],\n });\n\n for (const htmlFilePath of htmlFiles) {\n const relativePath = relative(sourceFullPath, htmlFilePath);\n const pathname = filePathToPathname(relativePath);\n\n pages.push({\n pathname,\n htmlFilePath,\n relativeHtmlPath: relativePath,\n });\n }\n } catch (error) {\n log.warn(`Error discovering HTML files: ${error}`);\n }\n\n return pages;\n}\n\nasync function indexPages(config: IndexerConfig): Promise<void> {\n log.text('\\n' + log.bold(log.cyan('Peam Static Site Indexer')) + '\\n');\n log.text(log.bold('Configuration:'));\n log.text(` Project Directory: ${log.gray(config.projectDir)}`);\n log.text(` Source Directory: ${log.gray(config.source)}`);\n log.text(` Glob Pattern: ${log.gray(config.glob)}`);\n log.text(` Output Directory: ${log.gray(config.outputDir)}`);\n log.text(` Index Filename: ${log.gray(config.indexFilename)}`);\n log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);\n if (config.exclude.length > 0) {\n log.text(` Exclude Patterns: ${log.gray(config.exclude.join(', '))}`);\n }\n log.text('');\n\n const sourcePath = join(config.projectDir, config.source);\n if (!existsSync(sourcePath)) {\n log.error(`Source directory not found: ${sourcePath}`);\n log.text(log.yellow(' Please build your site first or specify the correct --source directory'));\n process.exit(1);\n }\n\n const searchPaths = [join(config.source, 'robots.txt'), 'public/robots.txt', 'robots.txt'];\n\n const robotsResult = config.respectRobotsTxt\n ? loadRobotsTxt(config.projectDir, searchPaths, config.robotsTxtPath)\n : null;\n\n if (robotsResult && config.respectRobotsTxt) {\n log.info(`robots.txt loaded from ${log.cyan(relative(config.projectDir, robotsResult.path))}`);\n } else if (config.respectRobotsTxt) {\n log.info('No robots.txt found, all paths will be indexed');\n }\n\n log.text(log.bold('Discovering HTML files...'));\n log.text('');\n log.text(` Scanning: ${log.gray(config.source)}`);\n log.text(` Pattern: ${log.gray(config.glob)}`);\n log.text('');\n\n const discoveredPages = await discoverHtmlFiles(config.source, config.glob, config.projectDir);\n\n if (discoveredPages.length === 0) {\n log.text('');\n log.warn('No HTML files found');\n log.text(log.yellow(' Check that your source directory contains HTML files'));\n log.text(log.yellow(` Source: ${sourcePath}`));\n log.text(log.yellow(` Pattern: ${config.glob}`));\n process.exit(1);\n }\n\n const uniquePages = new Map<string, DiscoveredPage>();\n for (const page of discoveredPages) {\n if (!uniquePages.has(page.pathname)) {\n uniquePages.set(page.pathname, page);\n }\n }\n\n log.text('');\n log.success(`Found ${log.bold(uniquePages.size.toString())} unique pages`);\n log.text('');\n log.text(log.bold('Processing pages...'));\n log.text('');\n\n const processedPages: Array<{\n path: string;\n htmlFile: string;\n structuredPage: StructuredPage;\n }> = [];\n\n for (const [pathname, page] of uniquePages) {\n const result = shouldIncludePath(pathname, robotsResult?.parser ?? null, config.exclude, config.respectRobotsTxt);\n\n if (!result.included) {\n // Log the specific reason for exclusion\n if (result.reason === 'robots-txt') {\n log.error(`Excluded by robots.txt: ${pathname}`);\n } else if (result.reason === 'exclude-pattern') {\n log.error(`Excluded by pattern: ${pathname}`);\n }\n continue;\n }\n\n try {\n const html = readFileSync(page.htmlFilePath, 'utf-8');\n\n const structuredPage = parseHTML(html);\n\n if (!structuredPage) {\n log.warn(`No content extracted from ${log.gray(pathname)}`);\n continue;\n }\n\n log.success(`${log.cyan(pathname)}`);\n\n processedPages.push({\n path: pathname,\n htmlFile: page.relativeHtmlPath,\n structuredPage,\n });\n } catch (error) {\n log.error(`Error processing ${log.gray(pathname)}: ${error}`);\n }\n }\n\n log.text('');\n log.success(`Successfully processed ${log.bold(processedPages.length.toString())} pages`);\n log.text('');\n log.text(log.bold('Creating search index...'));\n log.text('');\n\n const searchIndexData = await buildSearchIndex(processedPages);\n\n log.success(`Added ${log.bold(processedPages.length.toString())} pages to search index`);\n log.text('');\n log.text(log.bold('Saving index...'));\n log.text('');\n\n const outputPath = join(config.projectDir, config.outputDir);\n mkdirSync(outputPath, { recursive: true });\n\n const generatedPath = join(outputPath, 'generated');\n mkdirSync(generatedPath, { recursive: true });\n\n const searchIndexFile = join(generatedPath, config.indexFilename);\n writeFileSync(searchIndexFile, JSON.stringify(searchIndexData));\n\n const indexJsContent = `// Auto-generated by Peam - DO NOT EDIT THIS FILE\nimport index from \"./generated/${config.indexFilename}\";\nexport default index;\n`;\n const indexJsFile = join(outputPath, 'index.js');\n writeFileSync(indexJsFile, indexJsContent);\n\n log.success(`Index saved to: ${log.cyan(relative(config.projectDir, searchIndexFile))}`);\n log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);\n log.text(\n ` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), 'utf8') / 1024).toFixed(2))} KB`\n );\n log.text('');\n log.success(log.bold('Indexing complete!'));\n log.text('');\n}\n\nfunction probeSourceDirectory(projectDir: string): string | null {\n const commonDirs = ['.next', '.build', '.out'];\n\n for (const dir of commonDirs) {\n const fullPath = join(projectDir, dir);\n if (existsSync(fullPath)) {\n return dir;\n }\n }\n\n return null;\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name('peam')\n .description('Peam static site indexer (Next.js, Hugo, etc.)')\n .version(packageJson.version)\n .option('--source <path>', 'Source directory containing HTML files (auto-detected if not provided)')\n .option('--glob <pattern>', 'Glob pattern for HTML files', '**/*.{html,htm}')\n .option('--output-dir <path>', 'Output directory for index', '.peam')\n .option('--index-filename <name>', 'Name of index file', 'index.json')\n .option('--ignore-robots-txt', 'Disable robots.txt checking')\n .option('--robots-path <path>', 'Custom path to robots.txt file')\n .option('--exclude <patterns>', 'Comma-separated exclude patterns', parseExcludePatterns, [])\n .option('--project-dir <path>', 'Project root directory', process.cwd())\n .addHelpText(\n 'after',\n `\nExamples:\n # Auto-detect build directory\n $ peam\n\n # Hugo\n $ peam --source public\n\n # Next.js\n $ peam --source .next\n\n # Custom output directory\n $ peam --source dist --glob \"**/*.html\"\n\n # Exclude patterns\n $ peam --exclude \"/admin/**,/api/*,/private-*\"\n\nFor Next.js 15+, the @peam-ai/next integration is recommended for production use.\n\nMore information: https://peam.ai\n `\n )\n .parse();\n\n const options = program.opts();\n\n try {\n let sourceDir = options.source;\n if (!sourceDir) {\n const probedDir = probeSourceDirectory(options.projectDir);\n if (probedDir) {\n sourceDir = probedDir;\n log.info(`Auto-detected source directory: ${log.cyan(probedDir)}`);\n log.text('');\n } else {\n log.error('No build output directory found');\n log.text(log.yellow(' Searched for: .next, .build, .out'));\n log.text(log.yellow(' Please build your site first or specify --source <directory>'));\n process.exit(1);\n }\n }\n\n const config: IndexerConfig = {\n source: sourceDir,\n glob: options.glob,\n outputDir: options.outputDir,\n indexFilename: options.indexFilename,\n respectRobotsTxt: !options.ignoreRobotsTxt,\n robotsTxtPath: options.robotsPath,\n exclude: options.exclude,\n projectDir: options.projectDir,\n };\n\n await indexPages(config);\n } catch (error) {\n log.text('');\n log.error(`Fatal error: ${error}`);\n process.exit(1);\n }\n}\n\nif (require.main === module) {\n main();\n}\n\nexport { indexPages, type IndexerConfig };\n"]}
1
+ {"version":3,"sources":["../src/cli.ts"],"names":["readFileSync","join","chalk","fg","relative","filePathToPathname","existsSync","loadRobotsTxt","shouldIncludePath","parseHTML","buildSearchIndex","createExporterFromConfig","Command"],"mappings":"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","file":"cli.js","sourcesContent":["/**\n * Peam Static Site Indexer\n *\n * Scans a static site output directory, discovers HTML files,\n * parses them into structured pages, and creates a searchable index.\n */\n\nimport { filePathToPathname, loadRobotsTxt, parseHTML, shouldIncludePath, type StructuredPage } from '@peam-ai/parser';\nimport { buildSearchIndex, createExporterFromConfig, type SearchExporterConfig } from '@peam-ai/search';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport fg from 'fast-glob';\nimport { existsSync, readFileSync } from 'fs';\nimport { join, relative } from 'path';\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\ninterface IndexerConfig {\n source: string;\n searchExporter: SearchExporterConfig;\n respectRobotsTxt: boolean;\n robotsTxtPath?: string;\n exclude: string[];\n glob: string;\n projectDir: string;\n}\n\ninterface DiscoveredPage {\n pathname: string;\n htmlFilePath: string;\n relativeHtmlPath: string;\n}\n\nfunction parseExcludePatterns(value: string): string[] {\n return value\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n}\n\n/**\n * Parse exporterConfig key=value pairs\n */\nfunction parseExporterConfigEntry(value: string, previous: string[] = []): string[] {\n return [...previous, value];\n}\n\n/**\n * Parse command line options and extract exporter configuration dynamically.\n * Supports --exporterConfig key=value pairs\n */\nfunction parseExporterConfig(options: Record<string, unknown>, exporterType: string): SearchExporterConfig {\n const exporterConfig: Record<string, unknown> = {};\n\n // Parse key=value pairs from --exporterConfig options\n if (Array.isArray(options.exporterConfig)) {\n for (const entry of options.exporterConfig) {\n if (typeof entry === 'string') {\n const [key, ...valueParts] = entry.split('=');\n const value = valueParts.join('=');\n if (key && value !== undefined) {\n exporterConfig[key.trim()] = value.trim();\n }\n }\n }\n }\n\n return {\n type: exporterType,\n config: exporterConfig,\n } as unknown as SearchExporterConfig;\n}\n\nconst log = {\n success: (message: string) => console.log(chalk.green('✓ ') + message),\n error: (message: string) => console.error(chalk.red('✗ ') + message),\n warn: (message: string) => console.warn(chalk.yellow('⚠ ') + message),\n info: (message: string) => console.log(chalk.blue('ℹ ') + message),\n text: (message: string) => console.log(message),\n\n cyan: (text: string) => chalk.cyan(text),\n gray: (text: string) => chalk.gray(text),\n bold: (text: string) => chalk.bold(text),\n yellow: (text: string) => chalk.yellow(text),\n red: (text: string) => chalk.red(text),\n green: (text: string) => chalk.green(text),\n};\n\nasync function discoverHtmlFiles(\n sourceDir: string,\n globPattern: string,\n projectDir: string\n): Promise<DiscoveredPage[]> {\n const pages: DiscoveredPage[] = [];\n\n try {\n const sourceFullPath = join(projectDir, sourceDir);\n\n const htmlFiles = await fg(globPattern, {\n cwd: sourceFullPath,\n absolute: true,\n onlyFiles: true,\n dot: false,\n ignore: ['**/_next/**', '**/_astro/**', '**/404.{html,htm}', '**/500.{html,htm}'],\n });\n\n for (const htmlFilePath of htmlFiles) {\n const relativePath = relative(sourceFullPath, htmlFilePath);\n const pathname = filePathToPathname(relativePath);\n\n pages.push({\n pathname,\n htmlFilePath,\n relativeHtmlPath: relativePath,\n });\n }\n } catch (error) {\n log.warn(`Error discovering HTML files: ${error}`);\n }\n\n return pages;\n}\n\nasync function indexPages(config: IndexerConfig): Promise<void> {\n log.text('\\n' + log.bold(log.cyan('Peam Static Site Indexer')) + '\\n');\n log.text(log.bold('Configuration:'));\n log.text(` Project Directory: ${log.gray(config.projectDir)}`);\n log.text(` Source Directory: ${log.gray(config.source)}`);\n log.text(` Glob Pattern: ${log.gray(config.glob)}`);\n log.text(` Exporter Type: ${log.gray(config.searchExporter.type)}`);\n log.text(` Exporter Config: ${log.gray(JSON.stringify(config.searchExporter.config, null, 2))}`);\n log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);\n if (config.exclude.length > 0) {\n log.text(` Exclude Patterns: ${log.gray(config.exclude.join(', '))}`);\n }\n log.text('');\n\n const sourcePath = join(config.projectDir, config.source);\n if (!existsSync(sourcePath)) {\n log.error(`Source directory not found: ${sourcePath}`);\n log.text(log.yellow(' Please build your site first or specify the correct --source directory'));\n process.exit(1);\n }\n\n const searchPaths = [join(config.source, 'robots.txt'), 'public/robots.txt', 'robots.txt'];\n\n const robotsResult = config.respectRobotsTxt\n ? loadRobotsTxt(config.projectDir, searchPaths, config.robotsTxtPath)\n : null;\n\n if (robotsResult && config.respectRobotsTxt) {\n log.info(`robots.txt loaded from ${log.cyan(relative(config.projectDir, robotsResult.path))}`);\n } else if (config.respectRobotsTxt) {\n log.info('No robots.txt found, all paths will be indexed');\n }\n\n log.text(log.bold('Discovering HTML files...'));\n log.text('');\n log.text(` Scanning: ${log.gray(config.source)}`);\n log.text(` Pattern: ${log.gray(config.glob)}`);\n log.text('');\n\n const discoveredPages = await discoverHtmlFiles(config.source, config.glob, config.projectDir);\n\n if (discoveredPages.length === 0) {\n log.text('');\n log.warn('No HTML files found');\n log.text(log.yellow(' Check that your source directory contains HTML files'));\n log.text(log.yellow(` Source: ${sourcePath}`));\n log.text(log.yellow(` Pattern: ${config.glob}`));\n process.exit(1);\n }\n\n const uniquePages = new Map<string, DiscoveredPage>();\n for (const page of discoveredPages) {\n if (!uniquePages.has(page.pathname)) {\n uniquePages.set(page.pathname, page);\n }\n }\n\n log.text('');\n log.success(`Found ${log.bold(uniquePages.size.toString())} unique pages`);\n log.text('');\n log.text(log.bold('Processing pages...'));\n log.text('');\n\n const processedPages: Array<{\n path: string;\n htmlFile: string;\n structuredPage: StructuredPage;\n }> = [];\n\n for (const [pathname, page] of uniquePages) {\n const result = shouldIncludePath(pathname, robotsResult?.parser ?? null, config.exclude, config.respectRobotsTxt);\n\n if (!result.included) {\n // Log the specific reason for exclusion\n if (result.reason === 'robots-txt') {\n log.error(`Excluded by robots.txt: ${pathname}`);\n } else if (result.reason === 'exclude-pattern') {\n log.error(`Excluded by pattern: ${pathname}`);\n }\n continue;\n }\n\n try {\n const html = readFileSync(page.htmlFilePath, 'utf-8');\n\n const structuredPage = parseHTML(html);\n\n if (!structuredPage) {\n log.warn(`No content extracted from ${log.gray(pathname)}`);\n continue;\n }\n\n log.success(`${log.cyan(pathname)}`);\n\n processedPages.push({\n path: pathname,\n htmlFile: page.relativeHtmlPath,\n structuredPage,\n });\n } catch (error) {\n log.error(`Error processing ${log.gray(pathname)}: ${error}`);\n }\n }\n\n log.text('');\n log.success(`Successfully processed ${log.bold(processedPages.length.toString())} pages`);\n log.text('');\n log.text(log.bold('Creating search index...'));\n log.text('');\n\n const searchIndexData = await buildSearchIndex(processedPages);\n\n log.success(`Added ${log.bold(processedPages.length.toString())} pages to search index`);\n log.text('');\n log.text(log.bold('Saving index...'));\n log.text('');\n\n const searchIndexExporter = createExporterFromConfig(config.searchExporter);\n await searchIndexExporter.export(searchIndexData);\n\n const indexPathDisplay =\n config.searchExporter.type === 'fileBased'\n ? relative(config.projectDir, join(config.projectDir, config.searchExporter.config.indexPath))\n : 'configured location';\n\n log.success(`Index saved to: ${log.cyan(indexPathDisplay)}`);\n log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);\n log.text(\n ` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), 'utf8') / 1024).toFixed(2))} KB`\n );\n log.text('');\n log.success(log.bold('Indexing complete!'));\n log.text('');\n}\n\nfunction probeSourceDirectory(projectDir: string): string | null {\n const commonDirs = ['.next', '.build', '.out'];\n\n for (const dir of commonDirs) {\n const fullPath = join(projectDir, dir);\n if (existsSync(fullPath)) {\n return dir;\n }\n }\n\n return null;\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name('peam')\n .description('Peam static site indexer (Next.js, Hugo, etc.)')\n .version(packageJson.version)\n .option('--source <path>', 'Source directory containing HTML files (auto-detected if not provided)')\n .option('--glob <pattern>', 'Glob pattern for HTML files', '**/*.{html,htm}')\n .option('--exporter <type>', 'Search exporter type', 'fileBased')\n .option('--exporterConfig <key=value>', 'Exporter config entry (repeatable)', parseExporterConfigEntry, [\n `baseDir=${process.cwd()}`,\n 'indexPath=.peam/index.json',\n ])\n .option('--ignore-robots-txt', 'Disable robots.txt checking')\n .option('--robots-path <path>', 'Custom path to robots.txt file')\n .option('--exclude <patterns>', 'Comma-separated exclude patterns', parseExcludePatterns, [])\n .option('--project-dir <path>', 'Project root directory', process.cwd())\n .addHelpText(\n 'after',\n `\nExamples:\n # Auto-detect build directory\n $ peam\n\n # Hugo\n $ peam --source public\n\n # Next.js\n $ peam --source .next\n\n # Custom index path using file-based exporter\n $ peam --source dist --exporterConfig indexPath=.search/index.json\n\n # Multiple exporter config entries\n $ peam --exporterConfig indexPath=custom/index.json --exporterConfig baseDir=/tmp\n\n # Exclude patterns\n $ peam --exclude \"/admin/**,/api/*,/private-*\"\n\nFor Next.js 15+, the @peam-ai/next integration is recommended for production use.\n\nMore information: https://peam.ai\n `\n )\n .parse();\n\n const options = program.opts();\n\n try {\n let sourceDir = options.source;\n if (!sourceDir) {\n const probedDir = probeSourceDirectory(options.projectDir);\n if (probedDir) {\n sourceDir = probedDir;\n log.info(`Auto-detected source directory: ${log.cyan(probedDir)}`);\n log.text('');\n } else {\n log.error('No build output directory found');\n log.text(log.yellow(' Searched for: .next, .build, .out'));\n log.text(log.yellow(' Please build your site first or specify --source <directory>'));\n process.exit(1);\n }\n }\n\n const searchExporter = parseExporterConfig(options, options.exporter);\n\n const config: IndexerConfig = {\n source: sourceDir,\n glob: options.glob,\n searchExporter,\n respectRobotsTxt: !options.ignoreRobotsTxt,\n robotsTxtPath: options.robotsPath,\n exclude: options.exclude,\n projectDir: options.projectDir,\n };\n\n await indexPages(config);\n } catch (error) {\n log.text('');\n log.error(`Fatal error: ${error}`);\n process.exit(1);\n }\n}\n\nif (require.main === module) {\n main();\n}\n\nexport { indexPages, type IndexerConfig };\n"]}
package/dist/index.d.mts CHANGED
@@ -1,13 +1,15 @@
1
+ import { SearchExporterConfig } from '@peam-ai/search';
2
+
1
3
  /**
2
4
  * Peam Static Site Indexer
3
5
  *
4
6
  * Scans a static site output directory, discovers HTML files,
5
7
  * parses them into structured pages, and creates a searchable index.
6
8
  */
9
+
7
10
  interface IndexerConfig {
8
11
  source: string;
9
- outputDir: string;
10
- indexFilename: string;
12
+ searchExporter: SearchExporterConfig;
11
13
  respectRobotsTxt: boolean;
12
14
  robotsTxtPath?: string;
13
15
  exclude: string[];
package/dist/index.d.ts CHANGED
@@ -1,13 +1,15 @@
1
+ import { SearchExporterConfig } from '@peam-ai/search';
2
+
1
3
  /**
2
4
  * Peam Static Site Indexer
3
5
  *
4
6
  * Scans a static site output directory, discovers HTML files,
5
7
  * parses them into structured pages, and creates a searchable index.
6
8
  */
9
+
7
10
  interface IndexerConfig {
8
11
  source: string;
9
- outputDir: string;
10
- indexFilename: string;
12
+ searchExporter: SearchExporterConfig;
11
13
  respectRobotsTxt: boolean;
12
14
  robotsTxtPath?: string;
13
15
  exclude: string[];
package/dist/index.js CHANGED
@@ -23,6 +23,27 @@ var packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, "../package.js
23
23
  function parseExcludePatterns(value) {
24
24
  return value.split(",").map((p) => p.trim()).filter(Boolean);
25
25
  }
26
+ function parseExporterConfigEntry(value, previous = []) {
27
+ return [...previous, value];
28
+ }
29
+ function parseExporterConfig(options, exporterType) {
30
+ const exporterConfig = {};
31
+ if (Array.isArray(options.exporterConfig)) {
32
+ for (const entry of options.exporterConfig) {
33
+ if (typeof entry === "string") {
34
+ const [key, ...valueParts] = entry.split("=");
35
+ const value = valueParts.join("=");
36
+ if (key && value !== void 0) {
37
+ exporterConfig[key.trim()] = value.trim();
38
+ }
39
+ }
40
+ }
41
+ }
42
+ return {
43
+ type: exporterType,
44
+ config: exporterConfig
45
+ };
46
+ }
26
47
  var log = {
27
48
  success: (message) => console.log(chalk__default.default.green("\u2713 ") + message),
28
49
  error: (message) => console.error(chalk__default.default.red("\u2717 ") + message),
@@ -68,8 +89,8 @@ async function indexPages(config) {
68
89
  log.text(` Project Directory: ${log.gray(config.projectDir)}`);
69
90
  log.text(` Source Directory: ${log.gray(config.source)}`);
70
91
  log.text(` Glob Pattern: ${log.gray(config.glob)}`);
71
- log.text(` Output Directory: ${log.gray(config.outputDir)}`);
72
- log.text(` Index Filename: ${log.gray(config.indexFilename)}`);
92
+ log.text(` Exporter Type: ${log.gray(config.searchExporter.type)}`);
93
+ log.text(` Exporter Config: ${log.gray(JSON.stringify(config.searchExporter.config, null, 2))}`);
73
94
  log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);
74
95
  if (config.exclude.length > 0) {
75
96
  log.text(` Exclude Patterns: ${log.gray(config.exclude.join(", "))}`);
@@ -151,19 +172,10 @@ async function indexPages(config) {
151
172
  log.text("");
152
173
  log.text(log.bold("Saving index..."));
153
174
  log.text("");
154
- const outputPath = path.join(config.projectDir, config.outputDir);
155
- fs.mkdirSync(outputPath, { recursive: true });
156
- const generatedPath = path.join(outputPath, "generated");
157
- fs.mkdirSync(generatedPath, { recursive: true });
158
- const searchIndexFile = path.join(generatedPath, config.indexFilename);
159
- fs.writeFileSync(searchIndexFile, JSON.stringify(searchIndexData));
160
- const indexJsContent = `// Auto-generated by Peam - DO NOT EDIT THIS FILE
161
- import index from "./generated/${config.indexFilename}";
162
- export default index;
163
- `;
164
- const indexJsFile = path.join(outputPath, "index.js");
165
- fs.writeFileSync(indexJsFile, indexJsContent);
166
- log.success(`Index saved to: ${log.cyan(path.relative(config.projectDir, searchIndexFile))}`);
175
+ const searchIndexExporter = search.createExporterFromConfig(config.searchExporter);
176
+ await searchIndexExporter.export(searchIndexData);
177
+ const indexPathDisplay = config.searchExporter.type === "fileBased" ? path.relative(config.projectDir, path.join(config.projectDir, config.searchExporter.config.indexPath)) : "configured location";
178
+ log.success(`Index saved to: ${log.cyan(indexPathDisplay)}`);
167
179
  log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);
168
180
  log.text(
169
181
  ` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), "utf8") / 1024).toFixed(2))} KB`
@@ -184,7 +196,10 @@ function probeSourceDirectory(projectDir) {
184
196
  }
185
197
  async function main() {
186
198
  const program = new commander.Command();
187
- program.name("peam").description("Peam static site indexer (Next.js, Hugo, etc.)").version(packageJson.version).option("--source <path>", "Source directory containing HTML files (auto-detected if not provided)").option("--glob <pattern>", "Glob pattern for HTML files", "**/*.{html,htm}").option("--output-dir <path>", "Output directory for index", ".peam").option("--index-filename <name>", "Name of index file", "index.json").option("--ignore-robots-txt", "Disable robots.txt checking").option("--robots-path <path>", "Custom path to robots.txt file").option("--exclude <patterns>", "Comma-separated exclude patterns", parseExcludePatterns, []).option("--project-dir <path>", "Project root directory", process.cwd()).addHelpText(
199
+ program.name("peam").description("Peam static site indexer (Next.js, Hugo, etc.)").version(packageJson.version).option("--source <path>", "Source directory containing HTML files (auto-detected if not provided)").option("--glob <pattern>", "Glob pattern for HTML files", "**/*.{html,htm}").option("--exporter <type>", "Search exporter type", "fileBased").option("--exporterConfig <key=value>", "Exporter config entry (repeatable)", parseExporterConfigEntry, [
200
+ `baseDir=${process.cwd()}`,
201
+ "indexPath=.peam/index.json"
202
+ ]).option("--ignore-robots-txt", "Disable robots.txt checking").option("--robots-path <path>", "Custom path to robots.txt file").option("--exclude <patterns>", "Comma-separated exclude patterns", parseExcludePatterns, []).option("--project-dir <path>", "Project root directory", process.cwd()).addHelpText(
188
203
  "after",
189
204
  `
190
205
  Examples:
@@ -197,8 +212,11 @@ Examples:
197
212
  # Next.js
198
213
  $ peam --source .next
199
214
 
200
- # Custom output directory
201
- $ peam --source dist --glob "**/*.html"
215
+ # Custom index path using file-based exporter
216
+ $ peam --source dist --exporterConfig indexPath=.search/index.json
217
+
218
+ # Multiple exporter config entries
219
+ $ peam --exporterConfig indexPath=custom/index.json --exporterConfig baseDir=/tmp
202
220
 
203
221
  # Exclude patterns
204
222
  $ peam --exclude "/admin/**,/api/*,/private-*"
@@ -224,11 +242,11 @@ More information: https://peam.ai
224
242
  process.exit(1);
225
243
  }
226
244
  }
245
+ const searchExporter = parseExporterConfig(options, options.exporter);
227
246
  const config = {
228
247
  source: sourceDir,
229
248
  glob: options.glob,
230
- outputDir: options.outputDir,
231
- indexFilename: options.indexFilename,
249
+ searchExporter,
232
250
  respectRobotsTxt: !options.ignoreRobotsTxt,
233
251
  robotsTxtPath: options.robotsPath,
234
252
  exclude: options.exclude,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"names":["readFileSync","join","chalk","fg","relative","filePathToPathname","existsSync","loadRobotsTxt","shouldIncludePath","parseHTML","buildSearchIndex","mkdirSync","writeFileSync","Command"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Peam Static Site Indexer\n *\n * Scans a static site output directory, discovers HTML files,\n * parses them into structured pages, and creates a searchable index.\n */\n\nimport { filePathToPathname, loadRobotsTxt, parseHTML, shouldIncludePath, type StructuredPage } from '@peam-ai/parser';\nimport { buildSearchIndex } from '@peam-ai/search';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport fg from 'fast-glob';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { join, relative } from 'path';\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\ninterface IndexerConfig {\n source: string;\n outputDir: string;\n indexFilename: string;\n respectRobotsTxt: boolean;\n robotsTxtPath?: string;\n exclude: string[];\n glob: string;\n projectDir: string;\n}\n\ninterface DiscoveredPage {\n pathname: string;\n htmlFilePath: string;\n relativeHtmlPath: string;\n}\n\nfunction parseExcludePatterns(value: string): string[] {\n return value\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n}\n\nconst log = {\n success: (message: string) => console.log(chalk.green('✓ ') + message),\n error: (message: string) => console.error(chalk.red('✗ ') + message),\n warn: (message: string) => console.warn(chalk.yellow('⚠ ') + message),\n info: (message: string) => console.log(chalk.blue('ℹ ') + message),\n text: (message: string) => console.log(message),\n\n cyan: (text: string) => chalk.cyan(text),\n gray: (text: string) => chalk.gray(text),\n bold: (text: string) => chalk.bold(text),\n yellow: (text: string) => chalk.yellow(text),\n red: (text: string) => chalk.red(text),\n green: (text: string) => chalk.green(text),\n};\n\nasync function discoverHtmlFiles(\n sourceDir: string,\n globPattern: string,\n projectDir: string\n): Promise<DiscoveredPage[]> {\n const pages: DiscoveredPage[] = [];\n\n try {\n const sourceFullPath = join(projectDir, sourceDir);\n\n const htmlFiles = await fg(globPattern, {\n cwd: sourceFullPath,\n absolute: true,\n onlyFiles: true,\n dot: false,\n ignore: ['**/_next/**', '**/_astro/**', '**/404.{html,htm}', '**/500.{html,htm}'],\n });\n\n for (const htmlFilePath of htmlFiles) {\n const relativePath = relative(sourceFullPath, htmlFilePath);\n const pathname = filePathToPathname(relativePath);\n\n pages.push({\n pathname,\n htmlFilePath,\n relativeHtmlPath: relativePath,\n });\n }\n } catch (error) {\n log.warn(`Error discovering HTML files: ${error}`);\n }\n\n return pages;\n}\n\nasync function indexPages(config: IndexerConfig): Promise<void> {\n log.text('\\n' + log.bold(log.cyan('Peam Static Site Indexer')) + '\\n');\n log.text(log.bold('Configuration:'));\n log.text(` Project Directory: ${log.gray(config.projectDir)}`);\n log.text(` Source Directory: ${log.gray(config.source)}`);\n log.text(` Glob Pattern: ${log.gray(config.glob)}`);\n log.text(` Output Directory: ${log.gray(config.outputDir)}`);\n log.text(` Index Filename: ${log.gray(config.indexFilename)}`);\n log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);\n if (config.exclude.length > 0) {\n log.text(` Exclude Patterns: ${log.gray(config.exclude.join(', '))}`);\n }\n log.text('');\n\n const sourcePath = join(config.projectDir, config.source);\n if (!existsSync(sourcePath)) {\n log.error(`Source directory not found: ${sourcePath}`);\n log.text(log.yellow(' Please build your site first or specify the correct --source directory'));\n process.exit(1);\n }\n\n const searchPaths = [join(config.source, 'robots.txt'), 'public/robots.txt', 'robots.txt'];\n\n const robotsResult = config.respectRobotsTxt\n ? loadRobotsTxt(config.projectDir, searchPaths, config.robotsTxtPath)\n : null;\n\n if (robotsResult && config.respectRobotsTxt) {\n log.info(`robots.txt loaded from ${log.cyan(relative(config.projectDir, robotsResult.path))}`);\n } else if (config.respectRobotsTxt) {\n log.info('No robots.txt found, all paths will be indexed');\n }\n\n log.text(log.bold('Discovering HTML files...'));\n log.text('');\n log.text(` Scanning: ${log.gray(config.source)}`);\n log.text(` Pattern: ${log.gray(config.glob)}`);\n log.text('');\n\n const discoveredPages = await discoverHtmlFiles(config.source, config.glob, config.projectDir);\n\n if (discoveredPages.length === 0) {\n log.text('');\n log.warn('No HTML files found');\n log.text(log.yellow(' Check that your source directory contains HTML files'));\n log.text(log.yellow(` Source: ${sourcePath}`));\n log.text(log.yellow(` Pattern: ${config.glob}`));\n process.exit(1);\n }\n\n const uniquePages = new Map<string, DiscoveredPage>();\n for (const page of discoveredPages) {\n if (!uniquePages.has(page.pathname)) {\n uniquePages.set(page.pathname, page);\n }\n }\n\n log.text('');\n log.success(`Found ${log.bold(uniquePages.size.toString())} unique pages`);\n log.text('');\n log.text(log.bold('Processing pages...'));\n log.text('');\n\n const processedPages: Array<{\n path: string;\n htmlFile: string;\n structuredPage: StructuredPage;\n }> = [];\n\n for (const [pathname, page] of uniquePages) {\n const result = shouldIncludePath(pathname, robotsResult?.parser ?? null, config.exclude, config.respectRobotsTxt);\n\n if (!result.included) {\n // Log the specific reason for exclusion\n if (result.reason === 'robots-txt') {\n log.error(`Excluded by robots.txt: ${pathname}`);\n } else if (result.reason === 'exclude-pattern') {\n log.error(`Excluded by pattern: ${pathname}`);\n }\n continue;\n }\n\n try {\n const html = readFileSync(page.htmlFilePath, 'utf-8');\n\n const structuredPage = parseHTML(html);\n\n if (!structuredPage) {\n log.warn(`No content extracted from ${log.gray(pathname)}`);\n continue;\n }\n\n log.success(`${log.cyan(pathname)}`);\n\n processedPages.push({\n path: pathname,\n htmlFile: page.relativeHtmlPath,\n structuredPage,\n });\n } catch (error) {\n log.error(`Error processing ${log.gray(pathname)}: ${error}`);\n }\n }\n\n log.text('');\n log.success(`Successfully processed ${log.bold(processedPages.length.toString())} pages`);\n log.text('');\n log.text(log.bold('Creating search index...'));\n log.text('');\n\n const searchIndexData = await buildSearchIndex(processedPages);\n\n log.success(`Added ${log.bold(processedPages.length.toString())} pages to search index`);\n log.text('');\n log.text(log.bold('Saving index...'));\n log.text('');\n\n const outputPath = join(config.projectDir, config.outputDir);\n mkdirSync(outputPath, { recursive: true });\n\n const generatedPath = join(outputPath, 'generated');\n mkdirSync(generatedPath, { recursive: true });\n\n const searchIndexFile = join(generatedPath, config.indexFilename);\n writeFileSync(searchIndexFile, JSON.stringify(searchIndexData));\n\n const indexJsContent = `// Auto-generated by Peam - DO NOT EDIT THIS FILE\nimport index from \"./generated/${config.indexFilename}\";\nexport default index;\n`;\n const indexJsFile = join(outputPath, 'index.js');\n writeFileSync(indexJsFile, indexJsContent);\n\n log.success(`Index saved to: ${log.cyan(relative(config.projectDir, searchIndexFile))}`);\n log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);\n log.text(\n ` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), 'utf8') / 1024).toFixed(2))} KB`\n );\n log.text('');\n log.success(log.bold('Indexing complete!'));\n log.text('');\n}\n\nfunction probeSourceDirectory(projectDir: string): string | null {\n const commonDirs = ['.next', '.build', '.out'];\n\n for (const dir of commonDirs) {\n const fullPath = join(projectDir, dir);\n if (existsSync(fullPath)) {\n return dir;\n }\n }\n\n return null;\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name('peam')\n .description('Peam static site indexer (Next.js, Hugo, etc.)')\n .version(packageJson.version)\n .option('--source <path>', 'Source directory containing HTML files (auto-detected if not provided)')\n .option('--glob <pattern>', 'Glob pattern for HTML files', '**/*.{html,htm}')\n .option('--output-dir <path>', 'Output directory for index', '.peam')\n .option('--index-filename <name>', 'Name of index file', 'index.json')\n .option('--ignore-robots-txt', 'Disable robots.txt checking')\n .option('--robots-path <path>', 'Custom path to robots.txt file')\n .option('--exclude <patterns>', 'Comma-separated exclude patterns', parseExcludePatterns, [])\n .option('--project-dir <path>', 'Project root directory', process.cwd())\n .addHelpText(\n 'after',\n `\nExamples:\n # Auto-detect build directory\n $ peam\n\n # Hugo\n $ peam --source public\n\n # Next.js\n $ peam --source .next\n\n # Custom output directory\n $ peam --source dist --glob \"**/*.html\"\n\n # Exclude patterns\n $ peam --exclude \"/admin/**,/api/*,/private-*\"\n\nFor Next.js 15+, the @peam-ai/next integration is recommended for production use.\n\nMore information: https://peam.ai\n `\n )\n .parse();\n\n const options = program.opts();\n\n try {\n let sourceDir = options.source;\n if (!sourceDir) {\n const probedDir = probeSourceDirectory(options.projectDir);\n if (probedDir) {\n sourceDir = probedDir;\n log.info(`Auto-detected source directory: ${log.cyan(probedDir)}`);\n log.text('');\n } else {\n log.error('No build output directory found');\n log.text(log.yellow(' Searched for: .next, .build, .out'));\n log.text(log.yellow(' Please build your site first or specify --source <directory>'));\n process.exit(1);\n }\n }\n\n const config: IndexerConfig = {\n source: sourceDir,\n glob: options.glob,\n outputDir: options.outputDir,\n indexFilename: options.indexFilename,\n respectRobotsTxt: !options.ignoreRobotsTxt,\n robotsTxtPath: options.robotsPath,\n exclude: options.exclude,\n projectDir: options.projectDir,\n };\n\n await indexPages(config);\n } catch (error) {\n log.text('');\n log.error(`Fatal error: ${error}`);\n process.exit(1);\n }\n}\n\nif (require.main === module) {\n main();\n}\n\nexport { indexPages, type IndexerConfig };\n"]}
1
+ {"version":3,"sources":["../src/cli.ts"],"names":["readFileSync","join","chalk","fg","relative","filePathToPathname","existsSync","loadRobotsTxt","shouldIncludePath","parseHTML","buildSearchIndex","createExporterFromConfig","Command"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Peam Static Site Indexer\n *\n * Scans a static site output directory, discovers HTML files,\n * parses them into structured pages, and creates a searchable index.\n */\n\nimport { filePathToPathname, loadRobotsTxt, parseHTML, shouldIncludePath, type StructuredPage } from '@peam-ai/parser';\nimport { buildSearchIndex, createExporterFromConfig, type SearchExporterConfig } from '@peam-ai/search';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport fg from 'fast-glob';\nimport { existsSync, readFileSync } from 'fs';\nimport { join, relative } from 'path';\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\ninterface IndexerConfig {\n source: string;\n searchExporter: SearchExporterConfig;\n respectRobotsTxt: boolean;\n robotsTxtPath?: string;\n exclude: string[];\n glob: string;\n projectDir: string;\n}\n\ninterface DiscoveredPage {\n pathname: string;\n htmlFilePath: string;\n relativeHtmlPath: string;\n}\n\nfunction parseExcludePatterns(value: string): string[] {\n return value\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n}\n\n/**\n * Parse exporterConfig key=value pairs\n */\nfunction parseExporterConfigEntry(value: string, previous: string[] = []): string[] {\n return [...previous, value];\n}\n\n/**\n * Parse command line options and extract exporter configuration dynamically.\n * Supports --exporterConfig key=value pairs\n */\nfunction parseExporterConfig(options: Record<string, unknown>, exporterType: string): SearchExporterConfig {\n const exporterConfig: Record<string, unknown> = {};\n\n // Parse key=value pairs from --exporterConfig options\n if (Array.isArray(options.exporterConfig)) {\n for (const entry of options.exporterConfig) {\n if (typeof entry === 'string') {\n const [key, ...valueParts] = entry.split('=');\n const value = valueParts.join('=');\n if (key && value !== undefined) {\n exporterConfig[key.trim()] = value.trim();\n }\n }\n }\n }\n\n return {\n type: exporterType,\n config: exporterConfig,\n } as unknown as SearchExporterConfig;\n}\n\nconst log = {\n success: (message: string) => console.log(chalk.green('✓ ') + message),\n error: (message: string) => console.error(chalk.red('✗ ') + message),\n warn: (message: string) => console.warn(chalk.yellow('⚠ ') + message),\n info: (message: string) => console.log(chalk.blue('ℹ ') + message),\n text: (message: string) => console.log(message),\n\n cyan: (text: string) => chalk.cyan(text),\n gray: (text: string) => chalk.gray(text),\n bold: (text: string) => chalk.bold(text),\n yellow: (text: string) => chalk.yellow(text),\n red: (text: string) => chalk.red(text),\n green: (text: string) => chalk.green(text),\n};\n\nasync function discoverHtmlFiles(\n sourceDir: string,\n globPattern: string,\n projectDir: string\n): Promise<DiscoveredPage[]> {\n const pages: DiscoveredPage[] = [];\n\n try {\n const sourceFullPath = join(projectDir, sourceDir);\n\n const htmlFiles = await fg(globPattern, {\n cwd: sourceFullPath,\n absolute: true,\n onlyFiles: true,\n dot: false,\n ignore: ['**/_next/**', '**/_astro/**', '**/404.{html,htm}', '**/500.{html,htm}'],\n });\n\n for (const htmlFilePath of htmlFiles) {\n const relativePath = relative(sourceFullPath, htmlFilePath);\n const pathname = filePathToPathname(relativePath);\n\n pages.push({\n pathname,\n htmlFilePath,\n relativeHtmlPath: relativePath,\n });\n }\n } catch (error) {\n log.warn(`Error discovering HTML files: ${error}`);\n }\n\n return pages;\n}\n\nasync function indexPages(config: IndexerConfig): Promise<void> {\n log.text('\\n' + log.bold(log.cyan('Peam Static Site Indexer')) + '\\n');\n log.text(log.bold('Configuration:'));\n log.text(` Project Directory: ${log.gray(config.projectDir)}`);\n log.text(` Source Directory: ${log.gray(config.source)}`);\n log.text(` Glob Pattern: ${log.gray(config.glob)}`);\n log.text(` Exporter Type: ${log.gray(config.searchExporter.type)}`);\n log.text(` Exporter Config: ${log.gray(JSON.stringify(config.searchExporter.config, null, 2))}`);\n log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);\n if (config.exclude.length > 0) {\n log.text(` Exclude Patterns: ${log.gray(config.exclude.join(', '))}`);\n }\n log.text('');\n\n const sourcePath = join(config.projectDir, config.source);\n if (!existsSync(sourcePath)) {\n log.error(`Source directory not found: ${sourcePath}`);\n log.text(log.yellow(' Please build your site first or specify the correct --source directory'));\n process.exit(1);\n }\n\n const searchPaths = [join(config.source, 'robots.txt'), 'public/robots.txt', 'robots.txt'];\n\n const robotsResult = config.respectRobotsTxt\n ? loadRobotsTxt(config.projectDir, searchPaths, config.robotsTxtPath)\n : null;\n\n if (robotsResult && config.respectRobotsTxt) {\n log.info(`robots.txt loaded from ${log.cyan(relative(config.projectDir, robotsResult.path))}`);\n } else if (config.respectRobotsTxt) {\n log.info('No robots.txt found, all paths will be indexed');\n }\n\n log.text(log.bold('Discovering HTML files...'));\n log.text('');\n log.text(` Scanning: ${log.gray(config.source)}`);\n log.text(` Pattern: ${log.gray(config.glob)}`);\n log.text('');\n\n const discoveredPages = await discoverHtmlFiles(config.source, config.glob, config.projectDir);\n\n if (discoveredPages.length === 0) {\n log.text('');\n log.warn('No HTML files found');\n log.text(log.yellow(' Check that your source directory contains HTML files'));\n log.text(log.yellow(` Source: ${sourcePath}`));\n log.text(log.yellow(` Pattern: ${config.glob}`));\n process.exit(1);\n }\n\n const uniquePages = new Map<string, DiscoveredPage>();\n for (const page of discoveredPages) {\n if (!uniquePages.has(page.pathname)) {\n uniquePages.set(page.pathname, page);\n }\n }\n\n log.text('');\n log.success(`Found ${log.bold(uniquePages.size.toString())} unique pages`);\n log.text('');\n log.text(log.bold('Processing pages...'));\n log.text('');\n\n const processedPages: Array<{\n path: string;\n htmlFile: string;\n structuredPage: StructuredPage;\n }> = [];\n\n for (const [pathname, page] of uniquePages) {\n const result = shouldIncludePath(pathname, robotsResult?.parser ?? null, config.exclude, config.respectRobotsTxt);\n\n if (!result.included) {\n // Log the specific reason for exclusion\n if (result.reason === 'robots-txt') {\n log.error(`Excluded by robots.txt: ${pathname}`);\n } else if (result.reason === 'exclude-pattern') {\n log.error(`Excluded by pattern: ${pathname}`);\n }\n continue;\n }\n\n try {\n const html = readFileSync(page.htmlFilePath, 'utf-8');\n\n const structuredPage = parseHTML(html);\n\n if (!structuredPage) {\n log.warn(`No content extracted from ${log.gray(pathname)}`);\n continue;\n }\n\n log.success(`${log.cyan(pathname)}`);\n\n processedPages.push({\n path: pathname,\n htmlFile: page.relativeHtmlPath,\n structuredPage,\n });\n } catch (error) {\n log.error(`Error processing ${log.gray(pathname)}: ${error}`);\n }\n }\n\n log.text('');\n log.success(`Successfully processed ${log.bold(processedPages.length.toString())} pages`);\n log.text('');\n log.text(log.bold('Creating search index...'));\n log.text('');\n\n const searchIndexData = await buildSearchIndex(processedPages);\n\n log.success(`Added ${log.bold(processedPages.length.toString())} pages to search index`);\n log.text('');\n log.text(log.bold('Saving index...'));\n log.text('');\n\n const searchIndexExporter = createExporterFromConfig(config.searchExporter);\n await searchIndexExporter.export(searchIndexData);\n\n const indexPathDisplay =\n config.searchExporter.type === 'fileBased'\n ? relative(config.projectDir, join(config.projectDir, config.searchExporter.config.indexPath))\n : 'configured location';\n\n log.success(`Index saved to: ${log.cyan(indexPathDisplay)}`);\n log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);\n log.text(\n ` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), 'utf8') / 1024).toFixed(2))} KB`\n );\n log.text('');\n log.success(log.bold('Indexing complete!'));\n log.text('');\n}\n\nfunction probeSourceDirectory(projectDir: string): string | null {\n const commonDirs = ['.next', '.build', '.out'];\n\n for (const dir of commonDirs) {\n const fullPath = join(projectDir, dir);\n if (existsSync(fullPath)) {\n return dir;\n }\n }\n\n return null;\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name('peam')\n .description('Peam static site indexer (Next.js, Hugo, etc.)')\n .version(packageJson.version)\n .option('--source <path>', 'Source directory containing HTML files (auto-detected if not provided)')\n .option('--glob <pattern>', 'Glob pattern for HTML files', '**/*.{html,htm}')\n .option('--exporter <type>', 'Search exporter type', 'fileBased')\n .option('--exporterConfig <key=value>', 'Exporter config entry (repeatable)', parseExporterConfigEntry, [\n `baseDir=${process.cwd()}`,\n 'indexPath=.peam/index.json',\n ])\n .option('--ignore-robots-txt', 'Disable robots.txt checking')\n .option('--robots-path <path>', 'Custom path to robots.txt file')\n .option('--exclude <patterns>', 'Comma-separated exclude patterns', parseExcludePatterns, [])\n .option('--project-dir <path>', 'Project root directory', process.cwd())\n .addHelpText(\n 'after',\n `\nExamples:\n # Auto-detect build directory\n $ peam\n\n # Hugo\n $ peam --source public\n\n # Next.js\n $ peam --source .next\n\n # Custom index path using file-based exporter\n $ peam --source dist --exporterConfig indexPath=.search/index.json\n\n # Multiple exporter config entries\n $ peam --exporterConfig indexPath=custom/index.json --exporterConfig baseDir=/tmp\n\n # Exclude patterns\n $ peam --exclude \"/admin/**,/api/*,/private-*\"\n\nFor Next.js 15+, the @peam-ai/next integration is recommended for production use.\n\nMore information: https://peam.ai\n `\n )\n .parse();\n\n const options = program.opts();\n\n try {\n let sourceDir = options.source;\n if (!sourceDir) {\n const probedDir = probeSourceDirectory(options.projectDir);\n if (probedDir) {\n sourceDir = probedDir;\n log.info(`Auto-detected source directory: ${log.cyan(probedDir)}`);\n log.text('');\n } else {\n log.error('No build output directory found');\n log.text(log.yellow(' Searched for: .next, .build, .out'));\n log.text(log.yellow(' Please build your site first or specify --source <directory>'));\n process.exit(1);\n }\n }\n\n const searchExporter = parseExporterConfig(options, options.exporter);\n\n const config: IndexerConfig = {\n source: sourceDir,\n glob: options.glob,\n searchExporter,\n respectRobotsTxt: !options.ignoreRobotsTxt,\n robotsTxtPath: options.robotsPath,\n exclude: options.exclude,\n projectDir: options.projectDir,\n };\n\n await indexPages(config);\n } catch (error) {\n log.text('');\n log.error(`Fatal error: ${error}`);\n process.exit(1);\n }\n}\n\nif (require.main === module) {\n main();\n}\n\nexport { indexPages, type IndexerConfig };\n"]}
package/dist/index.mjs CHANGED
@@ -1,16 +1,37 @@
1
1
  import { __require } from './chunk-BJTO5JO5.mjs';
2
2
  import { loadRobotsTxt, shouldIncludePath, parseHTML, filePathToPathname } from '@peam-ai/parser';
3
- import { buildSearchIndex } from '@peam-ai/search';
3
+ import { buildSearchIndex, createExporterFromConfig } from '@peam-ai/search';
4
4
  import chalk from 'chalk';
5
5
  import { Command } from 'commander';
6
6
  import fg from 'fast-glob';
7
- import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'fs';
7
+ import { readFileSync, existsSync } from 'fs';
8
8
  import { join, relative } from 'path';
9
9
 
10
10
  var packageJson = JSON.parse(readFileSync(join(__dirname, "../package.json"), "utf-8"));
11
11
  function parseExcludePatterns(value) {
12
12
  return value.split(",").map((p) => p.trim()).filter(Boolean);
13
13
  }
14
+ function parseExporterConfigEntry(value, previous = []) {
15
+ return [...previous, value];
16
+ }
17
+ function parseExporterConfig(options, exporterType) {
18
+ const exporterConfig = {};
19
+ if (Array.isArray(options.exporterConfig)) {
20
+ for (const entry of options.exporterConfig) {
21
+ if (typeof entry === "string") {
22
+ const [key, ...valueParts] = entry.split("=");
23
+ const value = valueParts.join("=");
24
+ if (key && value !== void 0) {
25
+ exporterConfig[key.trim()] = value.trim();
26
+ }
27
+ }
28
+ }
29
+ }
30
+ return {
31
+ type: exporterType,
32
+ config: exporterConfig
33
+ };
34
+ }
14
35
  var log = {
15
36
  success: (message) => console.log(chalk.green("\u2713 ") + message),
16
37
  error: (message) => console.error(chalk.red("\u2717 ") + message),
@@ -56,8 +77,8 @@ async function indexPages(config) {
56
77
  log.text(` Project Directory: ${log.gray(config.projectDir)}`);
57
78
  log.text(` Source Directory: ${log.gray(config.source)}`);
58
79
  log.text(` Glob Pattern: ${log.gray(config.glob)}`);
59
- log.text(` Output Directory: ${log.gray(config.outputDir)}`);
60
- log.text(` Index Filename: ${log.gray(config.indexFilename)}`);
80
+ log.text(` Exporter Type: ${log.gray(config.searchExporter.type)}`);
81
+ log.text(` Exporter Config: ${log.gray(JSON.stringify(config.searchExporter.config, null, 2))}`);
61
82
  log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);
62
83
  if (config.exclude.length > 0) {
63
84
  log.text(` Exclude Patterns: ${log.gray(config.exclude.join(", "))}`);
@@ -139,19 +160,10 @@ async function indexPages(config) {
139
160
  log.text("");
140
161
  log.text(log.bold("Saving index..."));
141
162
  log.text("");
142
- const outputPath = join(config.projectDir, config.outputDir);
143
- mkdirSync(outputPath, { recursive: true });
144
- const generatedPath = join(outputPath, "generated");
145
- mkdirSync(generatedPath, { recursive: true });
146
- const searchIndexFile = join(generatedPath, config.indexFilename);
147
- writeFileSync(searchIndexFile, JSON.stringify(searchIndexData));
148
- const indexJsContent = `// Auto-generated by Peam - DO NOT EDIT THIS FILE
149
- import index from "./generated/${config.indexFilename}";
150
- export default index;
151
- `;
152
- const indexJsFile = join(outputPath, "index.js");
153
- writeFileSync(indexJsFile, indexJsContent);
154
- log.success(`Index saved to: ${log.cyan(relative(config.projectDir, searchIndexFile))}`);
163
+ const searchIndexExporter = createExporterFromConfig(config.searchExporter);
164
+ await searchIndexExporter.export(searchIndexData);
165
+ const indexPathDisplay = config.searchExporter.type === "fileBased" ? relative(config.projectDir, join(config.projectDir, config.searchExporter.config.indexPath)) : "configured location";
166
+ log.success(`Index saved to: ${log.cyan(indexPathDisplay)}`);
155
167
  log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);
156
168
  log.text(
157
169
  ` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), "utf8") / 1024).toFixed(2))} KB`
@@ -172,7 +184,10 @@ function probeSourceDirectory(projectDir) {
172
184
  }
173
185
  async function main() {
174
186
  const program = new Command();
175
- program.name("peam").description("Peam static site indexer (Next.js, Hugo, etc.)").version(packageJson.version).option("--source <path>", "Source directory containing HTML files (auto-detected if not provided)").option("--glob <pattern>", "Glob pattern for HTML files", "**/*.{html,htm}").option("--output-dir <path>", "Output directory for index", ".peam").option("--index-filename <name>", "Name of index file", "index.json").option("--ignore-robots-txt", "Disable robots.txt checking").option("--robots-path <path>", "Custom path to robots.txt file").option("--exclude <patterns>", "Comma-separated exclude patterns", parseExcludePatterns, []).option("--project-dir <path>", "Project root directory", process.cwd()).addHelpText(
187
+ program.name("peam").description("Peam static site indexer (Next.js, Hugo, etc.)").version(packageJson.version).option("--source <path>", "Source directory containing HTML files (auto-detected if not provided)").option("--glob <pattern>", "Glob pattern for HTML files", "**/*.{html,htm}").option("--exporter <type>", "Search exporter type", "fileBased").option("--exporterConfig <key=value>", "Exporter config entry (repeatable)", parseExporterConfigEntry, [
188
+ `baseDir=${process.cwd()}`,
189
+ "indexPath=.peam/index.json"
190
+ ]).option("--ignore-robots-txt", "Disable robots.txt checking").option("--robots-path <path>", "Custom path to robots.txt file").option("--exclude <patterns>", "Comma-separated exclude patterns", parseExcludePatterns, []).option("--project-dir <path>", "Project root directory", process.cwd()).addHelpText(
176
191
  "after",
177
192
  `
178
193
  Examples:
@@ -185,8 +200,11 @@ Examples:
185
200
  # Next.js
186
201
  $ peam --source .next
187
202
 
188
- # Custom output directory
189
- $ peam --source dist --glob "**/*.html"
203
+ # Custom index path using file-based exporter
204
+ $ peam --source dist --exporterConfig indexPath=.search/index.json
205
+
206
+ # Multiple exporter config entries
207
+ $ peam --exporterConfig indexPath=custom/index.json --exporterConfig baseDir=/tmp
190
208
 
191
209
  # Exclude patterns
192
210
  $ peam --exclude "/admin/**,/api/*,/private-*"
@@ -212,11 +230,11 @@ More information: https://peam.ai
212
230
  process.exit(1);
213
231
  }
214
232
  }
233
+ const searchExporter = parseExporterConfig(options, options.exporter);
215
234
  const config = {
216
235
  source: sourceDir,
217
236
  glob: options.glob,
218
- outputDir: options.outputDir,
219
- indexFilename: options.indexFilename,
237
+ searchExporter,
220
238
  respectRobotsTxt: !options.ignoreRobotsTxt,
221
239
  robotsTxtPath: options.robotsPath,
222
240
  exclude: options.exclude,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Peam Static Site Indexer\n *\n * Scans a static site output directory, discovers HTML files,\n * parses them into structured pages, and creates a searchable index.\n */\n\nimport { filePathToPathname, loadRobotsTxt, parseHTML, shouldIncludePath, type StructuredPage } from '@peam-ai/parser';\nimport { buildSearchIndex } from '@peam-ai/search';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport fg from 'fast-glob';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { join, relative } from 'path';\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\ninterface IndexerConfig {\n source: string;\n outputDir: string;\n indexFilename: string;\n respectRobotsTxt: boolean;\n robotsTxtPath?: string;\n exclude: string[];\n glob: string;\n projectDir: string;\n}\n\ninterface DiscoveredPage {\n pathname: string;\n htmlFilePath: string;\n relativeHtmlPath: string;\n}\n\nfunction parseExcludePatterns(value: string): string[] {\n return value\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n}\n\nconst log = {\n success: (message: string) => console.log(chalk.green('✓ ') + message),\n error: (message: string) => console.error(chalk.red('✗ ') + message),\n warn: (message: string) => console.warn(chalk.yellow('⚠ ') + message),\n info: (message: string) => console.log(chalk.blue('ℹ ') + message),\n text: (message: string) => console.log(message),\n\n cyan: (text: string) => chalk.cyan(text),\n gray: (text: string) => chalk.gray(text),\n bold: (text: string) => chalk.bold(text),\n yellow: (text: string) => chalk.yellow(text),\n red: (text: string) => chalk.red(text),\n green: (text: string) => chalk.green(text),\n};\n\nasync function discoverHtmlFiles(\n sourceDir: string,\n globPattern: string,\n projectDir: string\n): Promise<DiscoveredPage[]> {\n const pages: DiscoveredPage[] = [];\n\n try {\n const sourceFullPath = join(projectDir, sourceDir);\n\n const htmlFiles = await fg(globPattern, {\n cwd: sourceFullPath,\n absolute: true,\n onlyFiles: true,\n dot: false,\n ignore: ['**/_next/**', '**/_astro/**', '**/404.{html,htm}', '**/500.{html,htm}'],\n });\n\n for (const htmlFilePath of htmlFiles) {\n const relativePath = relative(sourceFullPath, htmlFilePath);\n const pathname = filePathToPathname(relativePath);\n\n pages.push({\n pathname,\n htmlFilePath,\n relativeHtmlPath: relativePath,\n });\n }\n } catch (error) {\n log.warn(`Error discovering HTML files: ${error}`);\n }\n\n return pages;\n}\n\nasync function indexPages(config: IndexerConfig): Promise<void> {\n log.text('\\n' + log.bold(log.cyan('Peam Static Site Indexer')) + '\\n');\n log.text(log.bold('Configuration:'));\n log.text(` Project Directory: ${log.gray(config.projectDir)}`);\n log.text(` Source Directory: ${log.gray(config.source)}`);\n log.text(` Glob Pattern: ${log.gray(config.glob)}`);\n log.text(` Output Directory: ${log.gray(config.outputDir)}`);\n log.text(` Index Filename: ${log.gray(config.indexFilename)}`);\n log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);\n if (config.exclude.length > 0) {\n log.text(` Exclude Patterns: ${log.gray(config.exclude.join(', '))}`);\n }\n log.text('');\n\n const sourcePath = join(config.projectDir, config.source);\n if (!existsSync(sourcePath)) {\n log.error(`Source directory not found: ${sourcePath}`);\n log.text(log.yellow(' Please build your site first or specify the correct --source directory'));\n process.exit(1);\n }\n\n const searchPaths = [join(config.source, 'robots.txt'), 'public/robots.txt', 'robots.txt'];\n\n const robotsResult = config.respectRobotsTxt\n ? loadRobotsTxt(config.projectDir, searchPaths, config.robotsTxtPath)\n : null;\n\n if (robotsResult && config.respectRobotsTxt) {\n log.info(`robots.txt loaded from ${log.cyan(relative(config.projectDir, robotsResult.path))}`);\n } else if (config.respectRobotsTxt) {\n log.info('No robots.txt found, all paths will be indexed');\n }\n\n log.text(log.bold('Discovering HTML files...'));\n log.text('');\n log.text(` Scanning: ${log.gray(config.source)}`);\n log.text(` Pattern: ${log.gray(config.glob)}`);\n log.text('');\n\n const discoveredPages = await discoverHtmlFiles(config.source, config.glob, config.projectDir);\n\n if (discoveredPages.length === 0) {\n log.text('');\n log.warn('No HTML files found');\n log.text(log.yellow(' Check that your source directory contains HTML files'));\n log.text(log.yellow(` Source: ${sourcePath}`));\n log.text(log.yellow(` Pattern: ${config.glob}`));\n process.exit(1);\n }\n\n const uniquePages = new Map<string, DiscoveredPage>();\n for (const page of discoveredPages) {\n if (!uniquePages.has(page.pathname)) {\n uniquePages.set(page.pathname, page);\n }\n }\n\n log.text('');\n log.success(`Found ${log.bold(uniquePages.size.toString())} unique pages`);\n log.text('');\n log.text(log.bold('Processing pages...'));\n log.text('');\n\n const processedPages: Array<{\n path: string;\n htmlFile: string;\n structuredPage: StructuredPage;\n }> = [];\n\n for (const [pathname, page] of uniquePages) {\n const result = shouldIncludePath(pathname, robotsResult?.parser ?? null, config.exclude, config.respectRobotsTxt);\n\n if (!result.included) {\n // Log the specific reason for exclusion\n if (result.reason === 'robots-txt') {\n log.error(`Excluded by robots.txt: ${pathname}`);\n } else if (result.reason === 'exclude-pattern') {\n log.error(`Excluded by pattern: ${pathname}`);\n }\n continue;\n }\n\n try {\n const html = readFileSync(page.htmlFilePath, 'utf-8');\n\n const structuredPage = parseHTML(html);\n\n if (!structuredPage) {\n log.warn(`No content extracted from ${log.gray(pathname)}`);\n continue;\n }\n\n log.success(`${log.cyan(pathname)}`);\n\n processedPages.push({\n path: pathname,\n htmlFile: page.relativeHtmlPath,\n structuredPage,\n });\n } catch (error) {\n log.error(`Error processing ${log.gray(pathname)}: ${error}`);\n }\n }\n\n log.text('');\n log.success(`Successfully processed ${log.bold(processedPages.length.toString())} pages`);\n log.text('');\n log.text(log.bold('Creating search index...'));\n log.text('');\n\n const searchIndexData = await buildSearchIndex(processedPages);\n\n log.success(`Added ${log.bold(processedPages.length.toString())} pages to search index`);\n log.text('');\n log.text(log.bold('Saving index...'));\n log.text('');\n\n const outputPath = join(config.projectDir, config.outputDir);\n mkdirSync(outputPath, { recursive: true });\n\n const generatedPath = join(outputPath, 'generated');\n mkdirSync(generatedPath, { recursive: true });\n\n const searchIndexFile = join(generatedPath, config.indexFilename);\n writeFileSync(searchIndexFile, JSON.stringify(searchIndexData));\n\n const indexJsContent = `// Auto-generated by Peam - DO NOT EDIT THIS FILE\nimport index from \"./generated/${config.indexFilename}\";\nexport default index;\n`;\n const indexJsFile = join(outputPath, 'index.js');\n writeFileSync(indexJsFile, indexJsContent);\n\n log.success(`Index saved to: ${log.cyan(relative(config.projectDir, searchIndexFile))}`);\n log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);\n log.text(\n ` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), 'utf8') / 1024).toFixed(2))} KB`\n );\n log.text('');\n log.success(log.bold('Indexing complete!'));\n log.text('');\n}\n\nfunction probeSourceDirectory(projectDir: string): string | null {\n const commonDirs = ['.next', '.build', '.out'];\n\n for (const dir of commonDirs) {\n const fullPath = join(projectDir, dir);\n if (existsSync(fullPath)) {\n return dir;\n }\n }\n\n return null;\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name('peam')\n .description('Peam static site indexer (Next.js, Hugo, etc.)')\n .version(packageJson.version)\n .option('--source <path>', 'Source directory containing HTML files (auto-detected if not provided)')\n .option('--glob <pattern>', 'Glob pattern for HTML files', '**/*.{html,htm}')\n .option('--output-dir <path>', 'Output directory for index', '.peam')\n .option('--index-filename <name>', 'Name of index file', 'index.json')\n .option('--ignore-robots-txt', 'Disable robots.txt checking')\n .option('--robots-path <path>', 'Custom path to robots.txt file')\n .option('--exclude <patterns>', 'Comma-separated exclude patterns', parseExcludePatterns, [])\n .option('--project-dir <path>', 'Project root directory', process.cwd())\n .addHelpText(\n 'after',\n `\nExamples:\n # Auto-detect build directory\n $ peam\n\n # Hugo\n $ peam --source public\n\n # Next.js\n $ peam --source .next\n\n # Custom output directory\n $ peam --source dist --glob \"**/*.html\"\n\n # Exclude patterns\n $ peam --exclude \"/admin/**,/api/*,/private-*\"\n\nFor Next.js 15+, the @peam-ai/next integration is recommended for production use.\n\nMore information: https://peam.ai\n `\n )\n .parse();\n\n const options = program.opts();\n\n try {\n let sourceDir = options.source;\n if (!sourceDir) {\n const probedDir = probeSourceDirectory(options.projectDir);\n if (probedDir) {\n sourceDir = probedDir;\n log.info(`Auto-detected source directory: ${log.cyan(probedDir)}`);\n log.text('');\n } else {\n log.error('No build output directory found');\n log.text(log.yellow(' Searched for: .next, .build, .out'));\n log.text(log.yellow(' Please build your site first or specify --source <directory>'));\n process.exit(1);\n }\n }\n\n const config: IndexerConfig = {\n source: sourceDir,\n glob: options.glob,\n outputDir: options.outputDir,\n indexFilename: options.indexFilename,\n respectRobotsTxt: !options.ignoreRobotsTxt,\n robotsTxtPath: options.robotsPath,\n exclude: options.exclude,\n projectDir: options.projectDir,\n };\n\n await indexPages(config);\n } catch (error) {\n log.text('');\n log.error(`Fatal error: ${error}`);\n process.exit(1);\n }\n}\n\nif (require.main === module) {\n main();\n}\n\nexport { indexPages, type IndexerConfig };\n"]}
1
+ {"version":3,"sources":["../src/cli.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Peam Static Site Indexer\n *\n * Scans a static site output directory, discovers HTML files,\n * parses them into structured pages, and creates a searchable index.\n */\n\nimport { filePathToPathname, loadRobotsTxt, parseHTML, shouldIncludePath, type StructuredPage } from '@peam-ai/parser';\nimport { buildSearchIndex, createExporterFromConfig, type SearchExporterConfig } from '@peam-ai/search';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport fg from 'fast-glob';\nimport { existsSync, readFileSync } from 'fs';\nimport { join, relative } from 'path';\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\ninterface IndexerConfig {\n source: string;\n searchExporter: SearchExporterConfig;\n respectRobotsTxt: boolean;\n robotsTxtPath?: string;\n exclude: string[];\n glob: string;\n projectDir: string;\n}\n\ninterface DiscoveredPage {\n pathname: string;\n htmlFilePath: string;\n relativeHtmlPath: string;\n}\n\nfunction parseExcludePatterns(value: string): string[] {\n return value\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n}\n\n/**\n * Parse exporterConfig key=value pairs\n */\nfunction parseExporterConfigEntry(value: string, previous: string[] = []): string[] {\n return [...previous, value];\n}\n\n/**\n * Parse command line options and extract exporter configuration dynamically.\n * Supports --exporterConfig key=value pairs\n */\nfunction parseExporterConfig(options: Record<string, unknown>, exporterType: string): SearchExporterConfig {\n const exporterConfig: Record<string, unknown> = {};\n\n // Parse key=value pairs from --exporterConfig options\n if (Array.isArray(options.exporterConfig)) {\n for (const entry of options.exporterConfig) {\n if (typeof entry === 'string') {\n const [key, ...valueParts] = entry.split('=');\n const value = valueParts.join('=');\n if (key && value !== undefined) {\n exporterConfig[key.trim()] = value.trim();\n }\n }\n }\n }\n\n return {\n type: exporterType,\n config: exporterConfig,\n } as unknown as SearchExporterConfig;\n}\n\nconst log = {\n success: (message: string) => console.log(chalk.green('✓ ') + message),\n error: (message: string) => console.error(chalk.red('✗ ') + message),\n warn: (message: string) => console.warn(chalk.yellow('⚠ ') + message),\n info: (message: string) => console.log(chalk.blue('ℹ ') + message),\n text: (message: string) => console.log(message),\n\n cyan: (text: string) => chalk.cyan(text),\n gray: (text: string) => chalk.gray(text),\n bold: (text: string) => chalk.bold(text),\n yellow: (text: string) => chalk.yellow(text),\n red: (text: string) => chalk.red(text),\n green: (text: string) => chalk.green(text),\n};\n\nasync function discoverHtmlFiles(\n sourceDir: string,\n globPattern: string,\n projectDir: string\n): Promise<DiscoveredPage[]> {\n const pages: DiscoveredPage[] = [];\n\n try {\n const sourceFullPath = join(projectDir, sourceDir);\n\n const htmlFiles = await fg(globPattern, {\n cwd: sourceFullPath,\n absolute: true,\n onlyFiles: true,\n dot: false,\n ignore: ['**/_next/**', '**/_astro/**', '**/404.{html,htm}', '**/500.{html,htm}'],\n });\n\n for (const htmlFilePath of htmlFiles) {\n const relativePath = relative(sourceFullPath, htmlFilePath);\n const pathname = filePathToPathname(relativePath);\n\n pages.push({\n pathname,\n htmlFilePath,\n relativeHtmlPath: relativePath,\n });\n }\n } catch (error) {\n log.warn(`Error discovering HTML files: ${error}`);\n }\n\n return pages;\n}\n\nasync function indexPages(config: IndexerConfig): Promise<void> {\n log.text('\\n' + log.bold(log.cyan('Peam Static Site Indexer')) + '\\n');\n log.text(log.bold('Configuration:'));\n log.text(` Project Directory: ${log.gray(config.projectDir)}`);\n log.text(` Source Directory: ${log.gray(config.source)}`);\n log.text(` Glob Pattern: ${log.gray(config.glob)}`);\n log.text(` Exporter Type: ${log.gray(config.searchExporter.type)}`);\n log.text(` Exporter Config: ${log.gray(JSON.stringify(config.searchExporter.config, null, 2))}`);\n log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);\n if (config.exclude.length > 0) {\n log.text(` Exclude Patterns: ${log.gray(config.exclude.join(', '))}`);\n }\n log.text('');\n\n const sourcePath = join(config.projectDir, config.source);\n if (!existsSync(sourcePath)) {\n log.error(`Source directory not found: ${sourcePath}`);\n log.text(log.yellow(' Please build your site first or specify the correct --source directory'));\n process.exit(1);\n }\n\n const searchPaths = [join(config.source, 'robots.txt'), 'public/robots.txt', 'robots.txt'];\n\n const robotsResult = config.respectRobotsTxt\n ? loadRobotsTxt(config.projectDir, searchPaths, config.robotsTxtPath)\n : null;\n\n if (robotsResult && config.respectRobotsTxt) {\n log.info(`robots.txt loaded from ${log.cyan(relative(config.projectDir, robotsResult.path))}`);\n } else if (config.respectRobotsTxt) {\n log.info('No robots.txt found, all paths will be indexed');\n }\n\n log.text(log.bold('Discovering HTML files...'));\n log.text('');\n log.text(` Scanning: ${log.gray(config.source)}`);\n log.text(` Pattern: ${log.gray(config.glob)}`);\n log.text('');\n\n const discoveredPages = await discoverHtmlFiles(config.source, config.glob, config.projectDir);\n\n if (discoveredPages.length === 0) {\n log.text('');\n log.warn('No HTML files found');\n log.text(log.yellow(' Check that your source directory contains HTML files'));\n log.text(log.yellow(` Source: ${sourcePath}`));\n log.text(log.yellow(` Pattern: ${config.glob}`));\n process.exit(1);\n }\n\n const uniquePages = new Map<string, DiscoveredPage>();\n for (const page of discoveredPages) {\n if (!uniquePages.has(page.pathname)) {\n uniquePages.set(page.pathname, page);\n }\n }\n\n log.text('');\n log.success(`Found ${log.bold(uniquePages.size.toString())} unique pages`);\n log.text('');\n log.text(log.bold('Processing pages...'));\n log.text('');\n\n const processedPages: Array<{\n path: string;\n htmlFile: string;\n structuredPage: StructuredPage;\n }> = [];\n\n for (const [pathname, page] of uniquePages) {\n const result = shouldIncludePath(pathname, robotsResult?.parser ?? null, config.exclude, config.respectRobotsTxt);\n\n if (!result.included) {\n // Log the specific reason for exclusion\n if (result.reason === 'robots-txt') {\n log.error(`Excluded by robots.txt: ${pathname}`);\n } else if (result.reason === 'exclude-pattern') {\n log.error(`Excluded by pattern: ${pathname}`);\n }\n continue;\n }\n\n try {\n const html = readFileSync(page.htmlFilePath, 'utf-8');\n\n const structuredPage = parseHTML(html);\n\n if (!structuredPage) {\n log.warn(`No content extracted from ${log.gray(pathname)}`);\n continue;\n }\n\n log.success(`${log.cyan(pathname)}`);\n\n processedPages.push({\n path: pathname,\n htmlFile: page.relativeHtmlPath,\n structuredPage,\n });\n } catch (error) {\n log.error(`Error processing ${log.gray(pathname)}: ${error}`);\n }\n }\n\n log.text('');\n log.success(`Successfully processed ${log.bold(processedPages.length.toString())} pages`);\n log.text('');\n log.text(log.bold('Creating search index...'));\n log.text('');\n\n const searchIndexData = await buildSearchIndex(processedPages);\n\n log.success(`Added ${log.bold(processedPages.length.toString())} pages to search index`);\n log.text('');\n log.text(log.bold('Saving index...'));\n log.text('');\n\n const searchIndexExporter = createExporterFromConfig(config.searchExporter);\n await searchIndexExporter.export(searchIndexData);\n\n const indexPathDisplay =\n config.searchExporter.type === 'fileBased'\n ? relative(config.projectDir, join(config.projectDir, config.searchExporter.config.indexPath))\n : 'configured location';\n\n log.success(`Index saved to: ${log.cyan(indexPathDisplay)}`);\n log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);\n log.text(\n ` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), 'utf8') / 1024).toFixed(2))} KB`\n );\n log.text('');\n log.success(log.bold('Indexing complete!'));\n log.text('');\n}\n\nfunction probeSourceDirectory(projectDir: string): string | null {\n const commonDirs = ['.next', '.build', '.out'];\n\n for (const dir of commonDirs) {\n const fullPath = join(projectDir, dir);\n if (existsSync(fullPath)) {\n return dir;\n }\n }\n\n return null;\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name('peam')\n .description('Peam static site indexer (Next.js, Hugo, etc.)')\n .version(packageJson.version)\n .option('--source <path>', 'Source directory containing HTML files (auto-detected if not provided)')\n .option('--glob <pattern>', 'Glob pattern for HTML files', '**/*.{html,htm}')\n .option('--exporter <type>', 'Search exporter type', 'fileBased')\n .option('--exporterConfig <key=value>', 'Exporter config entry (repeatable)', parseExporterConfigEntry, [\n `baseDir=${process.cwd()}`,\n 'indexPath=.peam/index.json',\n ])\n .option('--ignore-robots-txt', 'Disable robots.txt checking')\n .option('--robots-path <path>', 'Custom path to robots.txt file')\n .option('--exclude <patterns>', 'Comma-separated exclude patterns', parseExcludePatterns, [])\n .option('--project-dir <path>', 'Project root directory', process.cwd())\n .addHelpText(\n 'after',\n `\nExamples:\n # Auto-detect build directory\n $ peam\n\n # Hugo\n $ peam --source public\n\n # Next.js\n $ peam --source .next\n\n # Custom index path using file-based exporter\n $ peam --source dist --exporterConfig indexPath=.search/index.json\n\n # Multiple exporter config entries\n $ peam --exporterConfig indexPath=custom/index.json --exporterConfig baseDir=/tmp\n\n # Exclude patterns\n $ peam --exclude \"/admin/**,/api/*,/private-*\"\n\nFor Next.js 15+, the @peam-ai/next integration is recommended for production use.\n\nMore information: https://peam.ai\n `\n )\n .parse();\n\n const options = program.opts();\n\n try {\n let sourceDir = options.source;\n if (!sourceDir) {\n const probedDir = probeSourceDirectory(options.projectDir);\n if (probedDir) {\n sourceDir = probedDir;\n log.info(`Auto-detected source directory: ${log.cyan(probedDir)}`);\n log.text('');\n } else {\n log.error('No build output directory found');\n log.text(log.yellow(' Searched for: .next, .build, .out'));\n log.text(log.yellow(' Please build your site first or specify --source <directory>'));\n process.exit(1);\n }\n }\n\n const searchExporter = parseExporterConfig(options, options.exporter);\n\n const config: IndexerConfig = {\n source: sourceDir,\n glob: options.glob,\n searchExporter,\n respectRobotsTxt: !options.ignoreRobotsTxt,\n robotsTxtPath: options.robotsPath,\n exclude: options.exclude,\n projectDir: options.projectDir,\n };\n\n await indexPages(config);\n } catch (error) {\n log.text('');\n log.error(`Fatal error: ${error}`);\n process.exit(1);\n }\n}\n\nif (require.main === module) {\n main();\n}\n\nexport { indexPages, type IndexerConfig };\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "peam",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Peam - AI that knows your website.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -64,11 +64,11 @@
64
64
  "chalk": "^4.1.2",
65
65
  "commander": "^12.1.0",
66
66
  "fast-glob": "^3.3.3",
67
- "@peam-ai/logger": "0.1.1",
68
- "@peam-ai/parser": "0.1.1",
69
- "@peam-ai/search": "0.1.1",
70
- "@peam-ai/server": "0.1.1",
71
- "@peam-ai/client": "0.1.1"
67
+ "@peam-ai/client": "0.1.2",
68
+ "@peam-ai/logger": "0.1.2",
69
+ "@peam-ai/parser": "0.1.2",
70
+ "@peam-ai/search": "0.1.2",
71
+ "@peam-ai/server": "0.1.2"
72
72
  },
73
73
  "devDependencies": {
74
74
  "@types/node": "^20.0.0",