markit-ai 0.1.1 → 0.1.3

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.
Files changed (57) hide show
  1. package/dist/commands/config.js +12 -6
  2. package/dist/commands/convert.js +3 -4
  3. package/dist/commands/formats.js +21 -5
  4. package/dist/commands/init.js +1 -1
  5. package/dist/commands/plugin.js +2 -2
  6. package/dist/converters/audio.d.ts +1 -1
  7. package/dist/converters/audio.js +23 -6
  8. package/dist/converters/csv.d.ts +1 -1
  9. package/dist/converters/csv.js +1 -1
  10. package/dist/converters/docx.d.ts +1 -1
  11. package/dist/converters/docx.js +1 -1
  12. package/dist/converters/epub.d.ts +1 -1
  13. package/dist/converters/epub.js +28 -8
  14. package/dist/converters/html.d.ts +1 -1
  15. package/dist/converters/html.js +1 -1
  16. package/dist/converters/image.d.ts +1 -1
  17. package/dist/converters/image.js +40 -10
  18. package/dist/converters/ipynb.d.ts +1 -1
  19. package/dist/converters/ipynb.js +6 -3
  20. package/dist/converters/json.d.ts +1 -1
  21. package/dist/converters/json.js +1 -1
  22. package/dist/converters/pdf.d.ts +1 -1
  23. package/dist/converters/pdf.js +1 -1
  24. package/dist/converters/plain-text.d.ts +1 -1
  25. package/dist/converters/plain-text.js +56 -10
  26. package/dist/converters/pptx.d.ts +1 -1
  27. package/dist/converters/pptx.js +39 -12
  28. package/dist/converters/rss.d.ts +1 -1
  29. package/dist/converters/rss.js +15 -11
  30. package/dist/converters/wikipedia.d.ts +1 -1
  31. package/dist/converters/wikipedia.js +4 -3
  32. package/dist/converters/xlsx.d.ts +1 -1
  33. package/dist/converters/xlsx.js +12 -5
  34. package/dist/converters/xml.d.ts +1 -1
  35. package/dist/converters/xml.js +2 -1
  36. package/dist/converters/yaml.d.ts +1 -1
  37. package/dist/converters/yaml.js +2 -1
  38. package/dist/converters/zip.d.ts +1 -1
  39. package/dist/converters/zip.js +3 -2
  40. package/dist/index.d.ts +20 -20
  41. package/dist/index.js +17 -17
  42. package/dist/main.js +13 -7
  43. package/dist/markit.d.ts +1 -1
  44. package/dist/markit.js +13 -16
  45. package/dist/plugins/api.js +1 -3
  46. package/dist/plugins/index.d.ts +3 -3
  47. package/dist/plugins/index.js +2 -2
  48. package/dist/plugins/installer.js +2 -2
  49. package/dist/plugins/types.d.ts +1 -1
  50. package/dist/providers/index.d.ts +2 -2
  51. package/dist/providers/index.js +2 -4
  52. package/dist/providers/openai.js +15 -4
  53. package/package.json +2 -1
  54. package/dist/llm.d.ts +0 -10
  55. package/dist/llm.js +0 -139
  56. package/dist/mill.d.ts +0 -18
  57. package/dist/mill.js +0 -123
@@ -1,7 +1,7 @@
1
- import { output, success, error, dim, bold } from "../utils/output.js";
2
- import { loadConfig, saveConfig, findConfigDir } from "../config.js";
1
+ import { findConfigDir, loadConfig, saveConfig } from "../config.js";
3
2
  import { getProvider, listProviders } from "../providers/index.js";
4
3
  import { EXIT_ERROR, EXIT_USER_ERROR } from "../utils/exit-codes.js";
4
+ import { bold, dim, error, output, success } from "../utils/output.js";
5
5
  export async function configShow(_args, options) {
6
6
  const config = loadConfig();
7
7
  const configDir = findConfigDir();
@@ -30,7 +30,8 @@ export async function configShow(_args, options) {
30
30
  if (provider) {
31
31
  // Resolve API key
32
32
  const apiKey = provider.envKeys.reduce((found, key) => found || process.env[key], undefined) || config.llm?.apiKey;
33
- const keySource = provider.envKeys.find((k) => process.env[k]) || (config.llm?.apiKey ? "config" : undefined);
33
+ const keySource = provider.envKeys.find((k) => process.env[k]) ||
34
+ (config.llm?.apiKey ? "config" : undefined);
34
35
  console.log(` ${dim("api key:")} ${apiKey ? `***${apiKey.slice(-4)} (${keySource})` : dim("not set")}`);
35
36
  console.log(` ${dim("api base:")} ${config.llm?.apiBase || provider.defaultBase}`);
36
37
  console.log(` ${dim("model:")} ${config.llm?.model || provider.defaultModel}`);
@@ -67,13 +68,18 @@ export async function configGet(key, options) {
67
68
  export async function configSet(key, value, options) {
68
69
  if (!findConfigDir()) {
69
70
  output(options, {
70
- json: () => ({ success: false, error: "No .markit/ directory. Run 'markit init'" }),
71
+ json: () => ({
72
+ success: false,
73
+ error: "No .markit/ directory. Run 'markit init'",
74
+ }),
71
75
  human: () => error("No .markit/ directory. Run 'markit init' first."),
72
76
  });
73
77
  process.exit(EXIT_ERROR);
74
78
  }
75
79
  // Secrets: read from stdin instead of args (avoids shell history)
76
- const isSecret = key.toLowerCase().includes("key") || key.toLowerCase().includes("secret") || key.toLowerCase().includes("token");
80
+ const isSecret = key.toLowerCase().includes("key") ||
81
+ key.toLowerCase().includes("secret") ||
82
+ key.toLowerCase().includes("token");
77
83
  let resolved;
78
84
  if (isSecret && !value) {
79
85
  // Prompt from stdin
@@ -109,7 +115,7 @@ export async function configSet(key, value, options) {
109
115
  else if (resolved === "false")
110
116
  parsed = false;
111
117
  else if (/^\d+$/.test(resolved))
112
- parsed = parseInt(resolved);
118
+ parsed = parseInt(resolved, 10);
113
119
  setNestedValue(config, key, parsed);
114
120
  saveConfig(config);
115
121
  output(options, {
@@ -1,11 +1,10 @@
1
1
  import { writeFileSync } from "node:fs";
2
- import { Markit } from "../markit.js";
3
2
  import { loadConfig } from "../config.js";
4
- import { createLlmFunctions } from "../providers/index.js";
3
+ import { Markit } from "../markit.js";
5
4
  import { loadAllPlugins } from "../plugins/loader.js";
6
- import { registerProvider } from "../providers/index.js";
7
- import { output, success, error, dim } from "../utils/output.js";
5
+ import { createLlmFunctions, registerProvider } from "../providers/index.js";
8
6
  import { EXIT_ERROR, EXIT_UNSUPPORTED } from "../utils/exit-codes.js";
7
+ import { dim, error, output, success } from "../utils/output.js";
9
8
  async function readStdin() {
10
9
  const chunks = [];
11
10
  for await (const chunk of process.stdin) {
@@ -1,5 +1,5 @@
1
- import { output, bold, dim } from "../utils/output.js";
2
1
  import { loadAllPlugins } from "../plugins/loader.js";
2
+ import { bold, dim, output } from "../utils/output.js";
3
3
  const BUILTIN_FORMATS = [
4
4
  { name: "PDF", extensions: [".pdf"], builtin: true },
5
5
  { name: "Word", extensions: [".docx"], builtin: true },
@@ -13,11 +13,27 @@ const BUILTIN_FORMATS = [
13
13
  { name: "JSON", extensions: [".json"], builtin: true },
14
14
  { name: "YAML", extensions: [".yaml", ".yml"], builtin: true },
15
15
  { name: "XML", extensions: [".xml", ".svg"], builtin: true },
16
- { name: "Images", extensions: [".jpg", ".png", ".gif", ".webp"], builtin: true },
17
- { name: "Audio", extensions: [".mp3", ".wav", ".m4a", ".flac"], builtin: true },
16
+ {
17
+ name: "Images",
18
+ extensions: [".jpg", ".png", ".gif", ".webp"],
19
+ builtin: true,
20
+ },
21
+ {
22
+ name: "Audio",
23
+ extensions: [".mp3", ".wav", ".m4a", ".flac"],
24
+ builtin: true,
25
+ },
18
26
  { name: "ZIP", extensions: [".zip"], builtin: true },
19
- { name: "Plain text", extensions: [".txt", ".md", ".rst", ".log"], builtin: true },
20
- { name: "Code", extensions: [".py", ".js", ".ts", ".go", ".rs", "..."], builtin: true },
27
+ {
28
+ name: "Plain text",
29
+ extensions: [".txt", ".md", ".rst", ".log"],
30
+ builtin: true,
31
+ },
32
+ {
33
+ name: "Code",
34
+ extensions: [".py", ".js", ".ts", ".go", ".rs", "..."],
35
+ builtin: true,
36
+ },
21
37
  { name: "URLs", extensions: ["http://", "https://"], builtin: true },
22
38
  { name: "Wikipedia", extensions: ["*.wikipedia.org"], builtin: true },
23
39
  ];
@@ -1,6 +1,6 @@
1
1
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { output, success, hint, cmd } from "../utils/output.js";
3
+ import { cmd, hint, output, success } from "../utils/output.js";
4
4
  const DATA_DIR = ".markit";
5
5
  export async function init(_args, options) {
6
6
  const root = join(process.cwd(), DATA_DIR);
@@ -1,6 +1,6 @@
1
- import { installPlugin, removePlugin, listInstalled } from "../plugins/installer.js";
2
- import { output, success, error, dim, bold } from "../utils/output.js";
1
+ import { installPlugin, listInstalled, removePlugin, } from "../plugins/installer.js";
3
2
  import { EXIT_ERROR } from "../utils/exit-codes.js";
3
+ import { bold, dim, error, output, success } from "../utils/output.js";
4
4
  export async function pluginInstall(source, options) {
5
5
  try {
6
6
  const result = await installPlugin(source);
@@ -1,4 +1,4 @@
1
- import type { Converter, ConversionResult, StreamInfo, MarkitOptions } from "../types.js";
1
+ import type { ConversionResult, Converter, MarkitOptions, StreamInfo } from "../types.js";
2
2
  export declare class AudioConverter implements Converter {
3
3
  name: string;
4
4
  accepts(streamInfo: StreamInfo): boolean;
@@ -1,11 +1,21 @@
1
- const EXTENSIONS = [".mp3", ".wav", ".m4a", ".mp4", ".ogg", ".flac", ".aac", ".wma"];
1
+ const EXTENSIONS = [
2
+ ".mp3",
3
+ ".wav",
4
+ ".m4a",
5
+ ".mp4",
6
+ ".ogg",
7
+ ".flac",
8
+ ".aac",
9
+ ".wma",
10
+ ];
2
11
  const MIMETYPES = ["audio/", "video/mp4"];
3
12
  export class AudioConverter {
4
13
  name = "audio";
5
14
  accepts(streamInfo) {
6
15
  if (streamInfo.extension && EXTENSIONS.includes(streamInfo.extension))
7
16
  return true;
8
- if (streamInfo.mimetype && MIMETYPES.some((m) => streamInfo.mimetype.startsWith(m)))
17
+ if (streamInfo.mimetype &&
18
+ MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m)))
9
19
  return true;
10
20
  return false;
11
21
  }
@@ -25,7 +35,9 @@ export class AudioConverter {
25
35
  Artist: common.artist,
26
36
  Album: common.album,
27
37
  Genre: common.genre?.join(", "),
28
- Track: common.track?.no ? `${common.track.no}${common.track.of ? ` of ${common.track.of}` : ""}` : undefined,
38
+ Track: common.track?.no
39
+ ? `${common.track.no}${common.track.of ? ` of ${common.track.of}` : ""}`
40
+ : undefined,
29
41
  Year: common.year ? String(common.year) : undefined,
30
42
  Duration: format.duration
31
43
  ? this.formatDuration(format.duration)
@@ -79,9 +91,14 @@ export class AudioConverter {
79
91
  }
80
92
  function guessMimetype(ext) {
81
93
  const map = {
82
- ".mp3": "audio/mpeg", ".wav": "audio/wav", ".m4a": "audio/mp4",
83
- ".mp4": "video/mp4", ".ogg": "audio/ogg", ".flac": "audio/flac",
84
- ".aac": "audio/aac", ".wma": "audio/x-ms-wma",
94
+ ".mp3": "audio/mpeg",
95
+ ".wav": "audio/wav",
96
+ ".m4a": "audio/mp4",
97
+ ".mp4": "video/mp4",
98
+ ".ogg": "audio/ogg",
99
+ ".flac": "audio/flac",
100
+ ".aac": "audio/aac",
101
+ ".wma": "audio/x-ms-wma",
85
102
  };
86
103
  return map[ext || ""] || "audio/mpeg";
87
104
  }
@@ -1,4 +1,4 @@
1
- import type { Converter, ConversionResult, StreamInfo } from "../types.js";
1
+ import type { ConversionResult, Converter, StreamInfo } from "../types.js";
2
2
  export declare class CsvConverter implements Converter {
3
3
  name: string;
4
4
  accepts(streamInfo: StreamInfo): boolean;
@@ -7,7 +7,7 @@ export class CsvConverter {
7
7
  return true;
8
8
  }
9
9
  if (streamInfo.mimetype &&
10
- MIMETYPES.some((m) => streamInfo.mimetype.startsWith(m))) {
10
+ MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m))) {
11
11
  return true;
12
12
  }
13
13
  return false;
@@ -1,4 +1,4 @@
1
- import type { Converter, ConversionResult, StreamInfo } from "../types.js";
1
+ import type { ConversionResult, Converter, StreamInfo } from "../types.js";
2
2
  export declare class DocxConverter implements Converter {
3
3
  name: string;
4
4
  accepts(streamInfo: StreamInfo): boolean;
@@ -11,7 +11,7 @@ export class DocxConverter {
11
11
  return true;
12
12
  }
13
13
  if (streamInfo.mimetype &&
14
- MIMETYPES.some((m) => streamInfo.mimetype.startsWith(m))) {
14
+ MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m))) {
15
15
  return true;
16
16
  }
17
17
  return false;
@@ -1,4 +1,4 @@
1
- import type { Converter, ConversionResult, StreamInfo } from "../types.js";
1
+ import type { ConversionResult, Converter, StreamInfo } from "../types.js";
2
2
  export declare class EpubConverter implements Converter {
3
3
  name: string;
4
4
  accepts(streamInfo: StreamInfo): boolean;
@@ -1,14 +1,19 @@
1
- import JSZip from "jszip";
2
1
  import { XMLParser } from "fast-xml-parser";
2
+ import JSZip from "jszip";
3
3
  import TurndownService from "turndown";
4
4
  const EXTENSIONS = [".epub"];
5
- const MIMETYPES = ["application/epub", "application/epub+zip", "application/x-epub+zip"];
5
+ const MIMETYPES = [
6
+ "application/epub",
7
+ "application/epub+zip",
8
+ "application/x-epub+zip",
9
+ ];
6
10
  export class EpubConverter {
7
11
  name = "epub";
8
12
  accepts(streamInfo) {
9
13
  if (streamInfo.extension && EXTENSIONS.includes(streamInfo.extension))
10
14
  return true;
11
- if (streamInfo.mimetype && MIMETYPES.some((m) => streamInfo.mimetype.startsWith(m)))
15
+ if (streamInfo.mimetype &&
16
+ MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m)))
12
17
  return true;
13
18
  return false;
14
19
  }
@@ -20,7 +25,9 @@ export class EpubConverter {
20
25
  textNodeName: "#text",
21
26
  });
22
27
  // Find content.opf path from container.xml
23
- const containerXml = await zip.file("META-INF/container.xml")?.async("string");
28
+ const containerXml = await zip
29
+ .file("META-INF/container.xml")
30
+ ?.async("string");
24
31
  if (!containerXml)
25
32
  throw new Error("Invalid EPUB: missing container.xml");
26
33
  const container = parser.parse(containerXml);
@@ -47,18 +54,31 @@ export class EpubConverter {
47
54
  };
48
55
  // Build manifest map (id → href)
49
56
  const manifestItems = opf.package?.manifest?.item;
50
- const itemList = Array.isArray(manifestItems) ? manifestItems : manifestItems ? [manifestItems] : [];
57
+ const itemList = Array.isArray(manifestItems)
58
+ ? manifestItems
59
+ : manifestItems
60
+ ? [manifestItems]
61
+ : [];
51
62
  const manifest = new Map();
52
63
  for (const item of itemList) {
53
64
  manifest.set(item["@_id"], item["@_href"]);
54
65
  }
55
66
  // Get spine order
56
67
  const spineItems = opf.package?.spine?.itemref;
57
- const spineList = Array.isArray(spineItems) ? spineItems : spineItems ? [spineItems] : [];
68
+ const spineList = Array.isArray(spineItems)
69
+ ? spineItems
70
+ : spineItems
71
+ ? [spineItems]
72
+ : [];
58
73
  const spineOrder = spineList.map((s) => s["@_idref"]);
59
74
  // Resolve file paths
60
- const basePath = opfPath.includes("/") ? opfPath.substring(0, opfPath.lastIndexOf("/")) : "";
61
- const turndown = new TurndownService({ headingStyle: "atx", codeBlockStyle: "fenced" });
75
+ const basePath = opfPath.includes("/")
76
+ ? opfPath.substring(0, opfPath.lastIndexOf("/"))
77
+ : "";
78
+ const turndown = new TurndownService({
79
+ headingStyle: "atx",
80
+ codeBlockStyle: "fenced",
81
+ });
62
82
  const sections = [];
63
83
  // Add metadata header
64
84
  const metaLines = [];
@@ -1,4 +1,4 @@
1
- import type { Converter, ConversionResult, StreamInfo } from "../types.js";
1
+ import type { ConversionResult, Converter, StreamInfo } from "../types.js";
2
2
  export declare class HtmlConverter implements Converter {
3
3
  name: string;
4
4
  accepts(streamInfo: StreamInfo): boolean;
@@ -8,7 +8,7 @@ export class HtmlConverter {
8
8
  return true;
9
9
  }
10
10
  if (streamInfo.mimetype &&
11
- MIMETYPES.some((m) => streamInfo.mimetype.startsWith(m))) {
11
+ MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m))) {
12
12
  return true;
13
13
  }
14
14
  return false;
@@ -1,4 +1,4 @@
1
- import type { Converter, ConversionResult, StreamInfo, MarkitOptions } from "../types.js";
1
+ import type { ConversionResult, Converter, MarkitOptions, StreamInfo } from "../types.js";
2
2
  export declare class ImageConverter implements Converter {
3
3
  name: string;
4
4
  accepts(streamInfo: StreamInfo): boolean;
@@ -1,11 +1,22 @@
1
- const EXTENSIONS = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".tiff", ".tif", ".bmp", ".svg"];
1
+ const EXTENSIONS = [
2
+ ".jpg",
3
+ ".jpeg",
4
+ ".png",
5
+ ".gif",
6
+ ".webp",
7
+ ".tiff",
8
+ ".tif",
9
+ ".bmp",
10
+ ".svg",
11
+ ];
2
12
  const MIMETYPES = ["image/"];
3
13
  export class ImageConverter {
4
14
  name = "image";
5
15
  accepts(streamInfo) {
6
16
  if (streamInfo.extension && EXTENSIONS.includes(streamInfo.extension))
7
17
  return true;
8
- if (streamInfo.mimetype && MIMETYPES.some((m) => streamInfo.mimetype.startsWith(m)))
18
+ if (streamInfo.mimetype &&
19
+ MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m)))
9
20
  return true;
10
21
  return false;
11
22
  }
@@ -16,11 +27,24 @@ export class ImageConverter {
16
27
  const exifr = await import("exifr");
17
28
  const metadata = await exifr.parse(input, {
18
29
  pick: [
19
- "ImageWidth", "ImageHeight", "Make", "Model",
20
- "DateTimeOriginal", "CreateDate", "GPSLatitude", "GPSLongitude",
21
- "Artist", "Copyright", "Description", "Title",
22
- "Keywords", "Software", "ExposureTime", "FNumber",
23
- "ISO", "FocalLength",
30
+ "ImageWidth",
31
+ "ImageHeight",
32
+ "Make",
33
+ "Model",
34
+ "DateTimeOriginal",
35
+ "CreateDate",
36
+ "GPSLatitude",
37
+ "GPSLongitude",
38
+ "Artist",
39
+ "Copyright",
40
+ "Description",
41
+ "Title",
42
+ "Keywords",
43
+ "Software",
44
+ "ExposureTime",
45
+ "FNumber",
46
+ "ISO",
47
+ "FocalLength",
24
48
  ],
25
49
  });
26
50
  if (metadata && Object.keys(metadata).length > 0) {
@@ -86,9 +110,15 @@ export class ImageConverter {
86
110
  }
87
111
  function guessMimetype(ext) {
88
112
  const map = {
89
- ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".png": "image/png",
90
- ".gif": "image/gif", ".webp": "image/webp", ".tiff": "image/tiff",
91
- ".tif": "image/tiff", ".bmp": "image/bmp", ".svg": "image/svg+xml",
113
+ ".jpg": "image/jpeg",
114
+ ".jpeg": "image/jpeg",
115
+ ".png": "image/png",
116
+ ".gif": "image/gif",
117
+ ".webp": "image/webp",
118
+ ".tiff": "image/tiff",
119
+ ".tif": "image/tiff",
120
+ ".bmp": "image/bmp",
121
+ ".svg": "image/svg+xml",
92
122
  };
93
123
  return map[ext || ""] || "image/png";
94
124
  }
@@ -1,4 +1,4 @@
1
- import type { Converter, ConversionResult, StreamInfo } from "../types.js";
1
+ import type { ConversionResult, Converter, StreamInfo } from "../types.js";
2
2
  export declare class IpynbConverter implements Converter {
3
3
  name: string;
4
4
  accepts(streamInfo: StreamInfo): boolean;
@@ -14,7 +14,7 @@ export class IpynbConverter {
14
14
  for (const cell of notebook.cells ?? []) {
15
15
  const source = Array.isArray(cell.source)
16
16
  ? cell.source.join("")
17
- : cell.source ?? "";
17
+ : (cell.source ?? "");
18
18
  if (cell.cell_type === "markdown") {
19
19
  sections.push(source);
20
20
  // Extract first heading as title
@@ -34,11 +34,14 @@ export class IpynbConverter {
34
34
  const outputs = [];
35
35
  for (const out of cell.outputs ?? []) {
36
36
  if (out.output_type === "stream") {
37
- const text = Array.isArray(out.text) ? out.text.join("") : out.text ?? "";
37
+ const text = Array.isArray(out.text)
38
+ ? out.text.join("")
39
+ : (out.text ?? "");
38
40
  if (text.trim())
39
41
  outputs.push(text.trim());
40
42
  }
41
- else if (out.output_type === "execute_result" || out.output_type === "display_data") {
43
+ else if (out.output_type === "execute_result" ||
44
+ out.output_type === "display_data") {
42
45
  const data = out.data;
43
46
  if (data?.["text/plain"]) {
44
47
  const plain = Array.isArray(data["text/plain"])
@@ -1,4 +1,4 @@
1
- import type { Converter, ConversionResult, StreamInfo } from "../types.js";
1
+ import type { ConversionResult, Converter, StreamInfo } from "../types.js";
2
2
  export declare class JsonConverter implements Converter {
3
3
  name: string;
4
4
  accepts(streamInfo: StreamInfo): boolean;
@@ -7,7 +7,7 @@ export class JsonConverter {
7
7
  return true;
8
8
  }
9
9
  if (streamInfo.mimetype &&
10
- MIMETYPES.some((m) => streamInfo.mimetype.startsWith(m))) {
10
+ MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m))) {
11
11
  return true;
12
12
  }
13
13
  return false;
@@ -1,4 +1,4 @@
1
- import type { Converter, ConversionResult, StreamInfo } from "../types.js";
1
+ import type { ConversionResult, Converter, StreamInfo } from "../types.js";
2
2
  export declare class PdfConverter implements Converter {
3
3
  name: string;
4
4
  accepts(streamInfo: StreamInfo): boolean;
@@ -7,7 +7,7 @@ export class PdfConverter {
7
7
  return true;
8
8
  }
9
9
  if (streamInfo.mimetype &&
10
- MIMETYPES.some((m) => streamInfo.mimetype.startsWith(m))) {
10
+ MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m))) {
11
11
  return true;
12
12
  }
13
13
  return false;
@@ -1,4 +1,4 @@
1
- import type { Converter, ConversionResult, StreamInfo } from "../types.js";
1
+ import type { ConversionResult, Converter, StreamInfo } from "../types.js";
2
2
  export declare class PlainTextConverter implements Converter {
3
3
  name: string;
4
4
  accepts(streamInfo: StreamInfo): boolean;
@@ -1,21 +1,66 @@
1
1
  const TEXT_EXTENSIONS = [
2
- ".txt", ".md", ".markdown", ".rst", ".log", ".cfg", ".ini", ".yaml", ".yml",
3
- ".toml", ".xml", ".svg", ".env", ".sh", ".bash", ".zsh", ".fish",
4
- ".py", ".js", ".ts", ".jsx", ".tsx", ".go", ".rs", ".rb", ".java",
5
- ".c", ".cpp", ".h", ".hpp", ".cs", ".swift", ".kt", ".scala",
6
- ".sql", ".r", ".m", ".lua", ".pl", ".php", ".ex", ".exs",
7
- ".zig", ".nim", ".v", ".d", ".hs", ".ml", ".clj",
8
- ".makefile", ".dockerfile",
2
+ ".txt",
3
+ ".md",
4
+ ".markdown",
5
+ ".rst",
6
+ ".log",
7
+ ".cfg",
8
+ ".ini",
9
+ ".yaml",
10
+ ".yml",
11
+ ".toml",
12
+ ".xml",
13
+ ".svg",
14
+ ".env",
15
+ ".sh",
16
+ ".bash",
17
+ ".zsh",
18
+ ".fish",
19
+ ".py",
20
+ ".js",
21
+ ".ts",
22
+ ".jsx",
23
+ ".tsx",
24
+ ".go",
25
+ ".rs",
26
+ ".rb",
27
+ ".java",
28
+ ".c",
29
+ ".cpp",
30
+ ".h",
31
+ ".hpp",
32
+ ".cs",
33
+ ".swift",
34
+ ".kt",
35
+ ".scala",
36
+ ".sql",
37
+ ".r",
38
+ ".m",
39
+ ".lua",
40
+ ".pl",
41
+ ".php",
42
+ ".ex",
43
+ ".exs",
44
+ ".zig",
45
+ ".nim",
46
+ ".v",
47
+ ".d",
48
+ ".hs",
49
+ ".ml",
50
+ ".clj",
51
+ ".makefile",
52
+ ".dockerfile",
9
53
  ];
10
54
  const TEXT_MIMETYPES = ["text/"];
11
55
  export class PlainTextConverter {
12
56
  name = "plain-text";
13
57
  accepts(streamInfo) {
14
- if (streamInfo.extension && TEXT_EXTENSIONS.includes(streamInfo.extension)) {
58
+ if (streamInfo.extension &&
59
+ TEXT_EXTENSIONS.includes(streamInfo.extension)) {
15
60
  return true;
16
61
  }
17
62
  if (streamInfo.mimetype &&
18
- TEXT_MIMETYPES.some((m) => streamInfo.mimetype.startsWith(m))) {
63
+ TEXT_MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m))) {
19
64
  return true;
20
65
  }
21
66
  // If nothing else matched and there's no extension, try to decode as text
@@ -28,7 +73,8 @@ export class PlainTextConverter {
28
73
  const charset = streamInfo.charset || "utf-8";
29
74
  const text = new TextDecoder(charset).decode(input);
30
75
  // If it's already markdown, return as-is
31
- if (streamInfo.extension === ".md" || streamInfo.extension === ".markdown") {
76
+ if (streamInfo.extension === ".md" ||
77
+ streamInfo.extension === ".markdown") {
32
78
  return { markdown: text };
33
79
  }
34
80
  // For code files, wrap in a fenced code block
@@ -1,4 +1,4 @@
1
- import type { Converter, ConversionResult, StreamInfo } from "../types.js";
1
+ import type { ConversionResult, Converter, StreamInfo } from "../types.js";
2
2
  export declare class PptxConverter implements Converter {
3
3
  name: string;
4
4
  accepts(streamInfo: StreamInfo): boolean;