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/LICENSE +661 -0
- package/README.md +116 -0
- package/ai/base.js +26 -0
- package/ai/chatgpt.js +973 -0
- package/ai/chatgpt_helper.js +137 -0
- package/ai/chatgpt_scroll_collector.js +193 -0
- package/ai/claude.js +410 -0
- package/ai/claude_react_reader.js +59 -0
- package/ai/copilot.js +413 -0
- package/ai/deepseek.js +155 -0
- package/ai/gemini.js +856 -0
- package/ai/gemini_cloud_assist.js +91 -0
- package/ai/google_ai_studio.js +116 -0
- package/ai/google_search_ai.js +114 -0
- package/ai/index.js +34 -0
- package/ai/lumo.js +101 -0
- package/ai/meta.js +110 -0
- package/ai/mistral.js +57 -0
- package/ai/notebooklm.js +140 -0
- package/ai/perplexity.js +85 -0
- package/ai/qwen.js +101 -0
- package/ai/z_ai.js +101 -0
- package/detection/detect-platform.js +100 -0
- package/detection/domains.js +45 -0
- package/lib/turndown.js +803 -0
- package/package.json +56 -0
- package/utils/html-to-markdown.js +374 -0
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
|
+
}
|