decant-core 1.0.0

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/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # decant-core
2
+
3
+ Shared AI chat platform parsers and detection logic for [Covai](https://github.com/Covai-Labs) browser extensions.
4
+
5
+ This package powers the AI chat extraction features in both [AI Chat Exporter](https://github.com/Covai-Labs/ai-chat-exporter) and [Decant](https://github.com/Covai-Labs/decant).
6
+
7
+ ## Supported Platforms
8
+
9
+ | Platform | Parser |
10
+ |----------|--------|
11
+ | ChatGPT | `ChatGPTParser` |
12
+ | Claude | `ClaudeParser` |
13
+ | Copilot | `CopilotParser` |
14
+ | DeepSeek | `DeepSeekParser` |
15
+ | Gemini | `GeminiParser` |
16
+ | Gemini Cloud Assist | `GeminiCloudAssistParser` |
17
+ | Google AI Studio | `GoogleAIStudioParser` |
18
+ | Google Search AI | `GoogleSearchAIParser` |
19
+ | Lumo | `LumoParser` |
20
+ | Meta AI | `MetaParser` |
21
+ | Mistral | `MistralParser` |
22
+ | NotebookLM | `NotebookLMParser` |
23
+ | Perplexity | `PerplexityParser` |
24
+ | Qwen | `QwenParser` |
25
+ | Z AI | `ZAiParser` |
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ npm install decant-core
31
+ ```
32
+
33
+ For local development:
34
+
35
+ ```bash
36
+ npm install decant-core@file:../parser-core
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ ```js
42
+ import { detectPlatform, parsers, isAiChatUrl } from 'decant-core';
43
+
44
+ // Check if a URL is an AI chat platform
45
+ if (isAiChatUrl(window.location.href)) {
46
+ const platform = detectPlatform(window.location.href);
47
+ const ParserClass = parsers.find((p) => p.platform === platform);
48
+
49
+ if (ParserClass) {
50
+ const parser = new ParserClass();
51
+ if (parser.canParse(window.location.href)) {
52
+ const result = parser.parse();
53
+ // result.title, result.messages, result.model, etc.
54
+ }
55
+ }
56
+ }
57
+ ```
58
+
59
+ ### Subpath imports
60
+
61
+ ```js
62
+ // Individual parser
63
+ import { ChatGPTParser } from 'decant-core';
64
+
65
+ // Detection helpers
66
+ import { detectPlatform, isAiChatUrl, AI_CHAT_DOMAINS } from 'decant-core';
67
+
68
+ // Utilities
69
+ import { convertToMarkdown, cleanMarkdown } from 'decant-core';
70
+ ```
71
+
72
+ ## Project Structure
73
+
74
+ ```
75
+ parser-core/
76
+ ai/ # Parser classes
77
+ base.js # Base parser class
78
+ chatgpt.js # ChatGPT parser + linearize
79
+ chatgpt_helper.js # Injected helper for ChatGPT scroll collection
80
+ chatgpt_scroll_collector.js # Scroll/dedup logic for ChatGPT
81
+ claude.js # Claude parser (DOM + API)
82
+ claude_react_reader.js # Injected helper for Claude React tree
83
+ copilot.js # Copilot parser (multi-domain)
84
+ deepseek.js # DeepSeek parser (DOM + API)
85
+ gemini.js # Gemini parser
86
+ gemini_cloud_assist.js # Gemini Cloud Assist parser
87
+ google_ai_studio.js # Google AI Studio parser
88
+ google_search_ai.js # Google Search AI / SGE parser
89
+ index.js # Barrel export
90
+ lumo.js # Lumo parser
91
+ meta.js # Meta AI parser
92
+ mistral.js # Mistral parser
93
+ notebooklm.js # NotebookLM parser
94
+ perplexity.js # Perplexity parser
95
+ qwen.js # Qwen parser
96
+ z_ai.js # Z AI parser
97
+ detection/ # Platform detection
98
+ detect-platform.js # detectPlatform(), isAiChatUrl(), parsers[]
99
+ domains.js # AI_CHAT_DOMAINS, URL_PATTERNS
100
+ lib/ # Vendored libraries
101
+ turndown.js # Turndown HTML→Markdown converter
102
+ utils/ # Utilities
103
+ html-to-markdown.js # AI-specific Turndown rules
104
+ ```
105
+
106
+ ## Development
107
+
108
+ ```bash
109
+ npm install
110
+ npm run lint
111
+ npm run format:check
112
+ ```
113
+
114
+ ## License
115
+
116
+ [AGPL-3.0](LICENSE)
package/ai/base.js ADDED
@@ -0,0 +1,26 @@
1
+ export class ChatParser {
2
+ name = 'Generic';
3
+
4
+ getPlatformName() {
5
+ return this.name || this.constructor.name.replace(/Parser$/, '');
6
+ }
7
+
8
+ constructor() {}
9
+
10
+ /**
11
+ * Checks if this parser can handle the current URL
12
+ * @param {string} url
13
+ * @returns {boolean}
14
+ */
15
+ isAvailable(_url) {
16
+ throw new Error('Not implemented');
17
+ }
18
+
19
+ /**
20
+ * Parses the current page content into a standardized format
21
+ * @returns {Promise<{ title: string, messages: Array<{role: string, content: string}>, metadata?: Record<string, string> }>}
22
+ */
23
+ async parse() {
24
+ throw new Error('Not implemented');
25
+ }
26
+ }