dsh-reference-anything 0.5.1 → 0.5.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/LICENSE +22 -22
- package/NOTICE.md +110 -110
- package/README.md +472 -459
- package/cordis.patch.yml +136 -136
- package/docs/release/0.4.4/README.md +75 -0
- package/{release-notes → docs/release}/0.4.4/features.json +36 -36
- package/docs/release/0.5.0/README.md +148 -0
- package/{release-notes → docs/release}/0.5.0/features.json +65 -65
- package/docs/release/0.5.1/README.md +33 -0
- package/docs/release/0.5.2/README.md +51 -0
- package/docs/release/0.5.2/features.json +29 -0
- package/{release-notes → docs/release}/README.md +42 -38
- package/images/agents/LICENSE +22 -22
- package/images/agents/README.md +7 -3
- package/images/agents/antigravity.svg +1 -1
- package/images/agents/cline.svg +1 -1
- package/images/agents/continue.svg +1 -1
- package/images/agents/copilot.svg +27 -0
- package/images/agents/crush.svg +1 -1
- package/images/agents/doubao.svg +1 -0
- package/images/agents/goose.svg +1 -1
- package/images/agents/omp.svg +1 -0
- package/images/agents/reasonix.svg +5 -5
- package/images/agents/teleagent.svg +1 -1
- package/images/agents/trae.svg +1 -1
- package/images/agents/vibe.svg +1 -1
- package/images/agents/workbuddy.svg +37 -37
- package/images/agents/zed.svg +1 -1
- package/lib/chat-import-compatibility.js +8 -5
- package/lib/client.js +36526 -4
- package/lib/contract.d.ts +4 -0
- package/lib/host.d.ts +2 -2
- package/lib/local-conversation-reader.js +16 -11
- package/lib/render.js +21 -21
- package/lib/store/spec.d.ts +9 -1
- package/lib/tool.js +3 -2
- package/lib/wire.d.ts +13 -1
- package/lib/wire.js +5 -4
- package/locale/en.json +6 -6
- package/locale/zh.json +6 -6
- package/opencli-plugin/chatgpt.js +128 -128
- package/opencli-plugin/claude.js +138 -138
- package/opencli-plugin/common.js +452 -452
- package/opencli-plugin/deepseek.js +155 -155
- package/opencli-plugin/gemini.js +169 -169
- package/opencli-plugin/grok.js +124 -124
- package/opencli-plugin/kimi.js +126 -126
- package/opencli-plugin/opencli-plugin.json +6 -6
- package/opencli-plugin/package.json +8 -8
- package/opencli-plugin/since-guard.js +45 -45
- package/package.json +263 -262
- package/vendor/chat-import-reader/LICENSE +22 -22
- package/vendor/chat-import-reader/LICENSE.fzstd +20 -20
- package/vendor/chat-import-reader/README.md +54 -48
- package/vendor/chat-import-reader/availability-worker.mjs +119 -114
- package/vendor/chat-import-reader/parsers.d.mts +6 -6
- package/vendor/chat-import-reader/parsers.mjs +13069 -11168
- package/vendor/chat-import-reader/scan-worker.mjs +7 -7
- package/vendor/chat-import-reader/scanners.mjs +5523 -4286
- package/vendor/chat-import-reader/upstream-sha256.json +114 -101
- package/release-notes/0.4.4/commands.png +0 -0
- package/release-notes/0.4.4/demos/agent-import.gif +0 -0
- package/release-notes/0.4.4/demos/chat-import-upgrade.gif +0 -0
- package/release-notes/0.4.4/demos/folders.gif +0 -0
- package/release-notes/0.4.4/demos/local-plugins.gif +0 -0
- package/release-notes/0.4.4/demos/shortcuts.gif +0 -0
- package/release-notes/0.4.4/files.png +0 -0
- package/release-notes/0.5.0/demos/agent-import.gif +0 -0
- package/release-notes/0.5.0/demos/chat-import-upgrade.gif +0 -0
- package/release-notes/0.5.0/demos/folders.gif +0 -0
- package/release-notes/0.5.0/demos/local-plugins.gif +0 -0
- package/release-notes/0.5.0/demos/local-references.gif +0 -0
- package/release-notes/0.5.0/demos/shortcuts.gif +0 -0
package/opencli-plugin/claude.js
CHANGED
|
@@ -1,138 +1,138 @@
|
|
|
1
|
-
import { domFallbackScript, registerProvider, sinceGuardSource } from './common.js'
|
|
2
|
-
// OpenCLI discovery marker: registerProvider below performs the cli() calls.
|
|
3
|
-
|
|
4
|
-
const shared = String.raw`
|
|
5
|
-
const organization = async () => {
|
|
6
|
-
const response = await fetch('/api/organizations', { credentials: 'include' })
|
|
7
|
-
if (response.status === 401 || response.status === 403) throw Object.assign(new Error('login required'), { code: 'AUTH' })
|
|
8
|
-
if (!response.ok) throw new Error('organizations HTTP ' + response.status)
|
|
9
|
-
const payload = await response.json()
|
|
10
|
-
const organizations = Array.isArray(payload) ? payload : payload.organizations || []
|
|
11
|
-
const item = organizations.find(value => value && (value.uuid || value.id))
|
|
12
|
-
if (!item) throw Object.assign(new Error('no Claude organization'), { code: 'AUTH' })
|
|
13
|
-
return String(item.uuid || item.id)
|
|
14
|
-
}
|
|
15
|
-
`
|
|
16
|
-
|
|
17
|
-
const historyScript = String.raw`async function (args) {
|
|
18
|
-
${shared}
|
|
19
|
-
const stopEarly = (${sinceGuardSource})(args && args.since)
|
|
20
|
-
const rows = []
|
|
21
|
-
try {
|
|
22
|
-
const org = await organization()
|
|
23
|
-
let offset = 0
|
|
24
|
-
for (let page = 0; page < 500; page++) {
|
|
25
|
-
const response = await fetch('/api/organizations/' + encodeURIComponent(org) + '/chat_conversations?limit=100&offset=' + offset, { credentials: 'include' })
|
|
26
|
-
if (response.status === 401 || response.status === 403) return JSON.stringify({ ok: false, code: 'AUTH' })
|
|
27
|
-
if (response.status === 429) return JSON.stringify({ ok: false, code: 'RATE_LIMIT' })
|
|
28
|
-
if (!response.ok) throw new Error('history HTTP ' + response.status)
|
|
29
|
-
const payload = await response.json()
|
|
30
|
-
const items = Array.isArray(payload) ? payload : payload.items || payload.chat_conversations || []
|
|
31
|
-
const pageStart = rows.length
|
|
32
|
-
for (const item of items) {
|
|
33
|
-
const id = String(item.uuid || item.id || '')
|
|
34
|
-
if (!id) continue
|
|
35
|
-
rows.push({ provider: 'claude', accountScope: '', id,
|
|
36
|
-
title: String(item.name || item.title || 'Untitled Claude chat'),
|
|
37
|
-
url: location.origin + '/chat/' + encodeURIComponent(id),
|
|
38
|
-
createdAt: String(item.created_at || item.createdAt || ''),
|
|
39
|
-
updatedAt: String(item.updated_at || item.updatedAt || item.created_at || ''),
|
|
40
|
-
messageCount: Number(item.message_count || item.messageCount || 0),
|
|
41
|
-
cursor: String(offset + items.length), partial: false })
|
|
42
|
-
}
|
|
43
|
-
if (items.length < 100) break
|
|
44
|
-
if (stopEarly(rows.slice(pageStart))) break
|
|
45
|
-
offset += items.length
|
|
46
|
-
}
|
|
47
|
-
return JSON.stringify({ ok: true, rows })
|
|
48
|
-
} catch (error) {
|
|
49
|
-
if (error && error.code === 'AUTH') return JSON.stringify({ ok: false, code: 'AUTH' })
|
|
50
|
-
const links = Array.from(document.querySelectorAll('a[href*="/chat/"]'))
|
|
51
|
-
const seen = new Set()
|
|
52
|
-
for (const link of links) {
|
|
53
|
-
const match = link.href.match(/\/chat\/([^/?#]+)/)
|
|
54
|
-
if (!match || seen.has(match[1])) continue
|
|
55
|
-
seen.add(match[1])
|
|
56
|
-
rows.push({ provider: 'claude', accountScope: '', id: match[1],
|
|
57
|
-
title: (link.textContent || '').trim() || 'Untitled Claude chat', url: link.href,
|
|
58
|
-
createdAt: '', updatedAt: '', messageCount: 0, cursor: '', partial: true })
|
|
59
|
-
}
|
|
60
|
-
return JSON.stringify({ ok: rows.length > 0, rows, message: String(error && error.message || error) })
|
|
61
|
-
}
|
|
62
|
-
}`
|
|
63
|
-
|
|
64
|
-
const detailScript = String.raw`async function (args) {
|
|
65
|
-
${shared}
|
|
66
|
-
const textOf = value => typeof value === 'string' ? value
|
|
67
|
-
: Array.isArray(value) ? value.map(textOf).filter(Boolean).join('\n')
|
|
68
|
-
: value && typeof value === 'object' ? textOf(value.text || value.content || value.value || value.markdown || '') : ''
|
|
69
|
-
try {
|
|
70
|
-
const org = await organization()
|
|
71
|
-
const url = '/api/organizations/' + encodeURIComponent(org) + '/chat_conversations/' + encodeURIComponent(args.id)
|
|
72
|
-
+ '?tree=True&rendering_mode=messages&render_all_tools=true'
|
|
73
|
-
const response = await fetch(url, { credentials: 'include' })
|
|
74
|
-
if (response.status === 401 || response.status === 403) return JSON.stringify({ ok: false, code: 'AUTH' })
|
|
75
|
-
if (response.status === 429) return JSON.stringify({ ok: false, code: 'RATE_LIMIT' })
|
|
76
|
-
if (!response.ok) throw new Error('detail HTTP ' + response.status)
|
|
77
|
-
const payload = await response.json()
|
|
78
|
-
const messages = payload.chat_messages || payload.messages || (payload.conversation && payload.conversation.chat_messages) || []
|
|
79
|
-
const byId = new Map(messages.map(message => [String(message.uuid || message.id || ''), message]))
|
|
80
|
-
const childIds = new Set(messages.map(message => String(message.parent_message_uuid || message.parent_uuid || message.parent_id || '')).filter(Boolean))
|
|
81
|
-
const requestedLeaf = String(payload.current_leaf_message_uuid || payload.current_message_uuid || payload.current_node_uuid || '')
|
|
82
|
-
let leaf = requestedLeaf && byId.has(requestedLeaf) ? requestedLeaf : ''
|
|
83
|
-
if (!leaf) {
|
|
84
|
-
const leaves = messages.filter(message => !childIds.has(String(message.uuid || message.id || '')))
|
|
85
|
-
leaf = String((leaves[leaves.length - 1] || {}).uuid || (leaves[leaves.length - 1] || {}).id || '')
|
|
86
|
-
}
|
|
87
|
-
const active = new Set()
|
|
88
|
-
for (let id = leaf, guard = 0; id && guard++ < messages.length + 1;) {
|
|
89
|
-
active.add(id)
|
|
90
|
-
const message = byId.get(id)
|
|
91
|
-
id = message ? String(message.parent_message_uuid || message.parent_uuid || message.parent_id || '') : ''
|
|
92
|
-
}
|
|
93
|
-
const ordered = messages.slice().sort((a, b) => String(a.created_at || '').localeCompare(String(b.created_at || '')))
|
|
94
|
-
const rows = ordered.map((message, ordinal) => {
|
|
95
|
-
const id = String(message.uuid || message.id || ordinal)
|
|
96
|
-
const sender = String(message.sender || message.role || '').toLowerCase()
|
|
97
|
-
const content = message.content || message.text || message.content_blocks || ''
|
|
98
|
-
const attachments = (message.attachments || message.files || []).map((file, index) => {
|
|
99
|
-
const candidate = String(file.download_url || file.url || '')
|
|
100
|
-
let locator = ''
|
|
101
|
-
try { if (candidate) { const url = new URL(candidate, location.origin); if (url.origin === location.origin && url.pathname !== '/') locator = url.pathname + url.search } } catch {}
|
|
102
|
-
const name = String(file.name || file.file_name || 'attachment')
|
|
103
|
-
const mimeType = String(file.mime_type || file.mimeType || '')
|
|
104
|
-
return { attachmentId: String(file.id || file.uuid || index), name: String(file.name || file.file_name || 'attachment'),
|
|
105
|
-
kind: mimeType.startsWith('image/') || /\.(?:gif|jpe?g|png|webp)$/i.test(name) ? 'image' : 'file',
|
|
106
|
-
mimeType, size: Number(file.size || 0),
|
|
107
|
-
locator, status: locator ? 'available' : 'unavailable' }
|
|
108
|
-
})
|
|
109
|
-
return { conversationId: args.id, ordinal, messageId: id,
|
|
110
|
-
parentId: String(message.parent_message_uuid || message.parent_uuid || message.parent_id || ''),
|
|
111
|
-
branchId: String(message.branch_uuid || ''), activeBranch: active.size ? active.has(id) : true,
|
|
112
|
-
role: /assistant|claude|model/.test(sender) ? 'assistant' : 'user', text: textOf(content),
|
|
113
|
-
createdAt: String(message.created_at || message.createdAt || ''), attachmentsJson: JSON.stringify(attachments), partial: false }
|
|
114
|
-
}).filter(row => row.text || row.attachmentsJson !== '[]')
|
|
115
|
-
return JSON.stringify({ ok: rows.length > 0, rows })
|
|
116
|
-
} catch (error) {
|
|
117
|
-
if (error && error.code === 'AUTH') return JSON.stringify({ ok: false, code: 'AUTH' })
|
|
118
|
-
return JSON.stringify({ ok: false, message: String(error && error.message || error) })
|
|
119
|
-
}
|
|
120
|
-
}`
|
|
121
|
-
|
|
122
|
-
export const whoamiScript = String.raw`async function () {
|
|
123
|
-
const response = await fetch('/api/account', { credentials: 'include', headers: { Accept: 'application/json' } })
|
|
124
|
-
if (response.status === 401 || response.status === 403) return JSON.stringify({ ok: false, code: 'AUTH' })
|
|
125
|
-
if (response.status === 429) return JSON.stringify({ ok: false, code: 'RATE_LIMIT' })
|
|
126
|
-
if (!response.ok) return JSON.stringify({ ok: false, message: 'account HTTP ' + response.status })
|
|
127
|
-
const payload = await response.json()
|
|
128
|
-
const identity = typeof payload.email_address === 'string' ? payload.email_address.trim() : ''
|
|
129
|
-
if (!identity) return JSON.stringify({ ok: false, message: 'Claude stable account identity unavailable' })
|
|
130
|
-
return JSON.stringify({ ok: true, identity })
|
|
131
|
-
}`
|
|
132
|
-
|
|
133
|
-
registerProvider({
|
|
134
|
-
site: 'dsh-claude', provider: 'Claude', domain: 'claude.ai', home: 'https://claude.ai/',
|
|
135
|
-
conversationUrl: id => `https://claude.ai/chat/${encodeURIComponent(id)}`,
|
|
136
|
-
whoamiScript,
|
|
137
|
-
historyScript, detailScript, fallbackScript: domFallbackScript,
|
|
138
|
-
})
|
|
1
|
+
import { domFallbackScript, registerProvider, sinceGuardSource } from './common.js'
|
|
2
|
+
// OpenCLI discovery marker: registerProvider below performs the cli() calls.
|
|
3
|
+
|
|
4
|
+
const shared = String.raw`
|
|
5
|
+
const organization = async () => {
|
|
6
|
+
const response = await fetch('/api/organizations', { credentials: 'include' })
|
|
7
|
+
if (response.status === 401 || response.status === 403) throw Object.assign(new Error('login required'), { code: 'AUTH' })
|
|
8
|
+
if (!response.ok) throw new Error('organizations HTTP ' + response.status)
|
|
9
|
+
const payload = await response.json()
|
|
10
|
+
const organizations = Array.isArray(payload) ? payload : payload.organizations || []
|
|
11
|
+
const item = organizations.find(value => value && (value.uuid || value.id))
|
|
12
|
+
if (!item) throw Object.assign(new Error('no Claude organization'), { code: 'AUTH' })
|
|
13
|
+
return String(item.uuid || item.id)
|
|
14
|
+
}
|
|
15
|
+
`
|
|
16
|
+
|
|
17
|
+
const historyScript = String.raw`async function (args) {
|
|
18
|
+
${shared}
|
|
19
|
+
const stopEarly = (${sinceGuardSource})(args && args.since)
|
|
20
|
+
const rows = []
|
|
21
|
+
try {
|
|
22
|
+
const org = await organization()
|
|
23
|
+
let offset = 0
|
|
24
|
+
for (let page = 0; page < 500; page++) {
|
|
25
|
+
const response = await fetch('/api/organizations/' + encodeURIComponent(org) + '/chat_conversations?limit=100&offset=' + offset, { credentials: 'include' })
|
|
26
|
+
if (response.status === 401 || response.status === 403) return JSON.stringify({ ok: false, code: 'AUTH' })
|
|
27
|
+
if (response.status === 429) return JSON.stringify({ ok: false, code: 'RATE_LIMIT' })
|
|
28
|
+
if (!response.ok) throw new Error('history HTTP ' + response.status)
|
|
29
|
+
const payload = await response.json()
|
|
30
|
+
const items = Array.isArray(payload) ? payload : payload.items || payload.chat_conversations || []
|
|
31
|
+
const pageStart = rows.length
|
|
32
|
+
for (const item of items) {
|
|
33
|
+
const id = String(item.uuid || item.id || '')
|
|
34
|
+
if (!id) continue
|
|
35
|
+
rows.push({ provider: 'claude', accountScope: '', id,
|
|
36
|
+
title: String(item.name || item.title || 'Untitled Claude chat'),
|
|
37
|
+
url: location.origin + '/chat/' + encodeURIComponent(id),
|
|
38
|
+
createdAt: String(item.created_at || item.createdAt || ''),
|
|
39
|
+
updatedAt: String(item.updated_at || item.updatedAt || item.created_at || ''),
|
|
40
|
+
messageCount: Number(item.message_count || item.messageCount || 0),
|
|
41
|
+
cursor: String(offset + items.length), partial: false })
|
|
42
|
+
}
|
|
43
|
+
if (items.length < 100) break
|
|
44
|
+
if (stopEarly(rows.slice(pageStart))) break
|
|
45
|
+
offset += items.length
|
|
46
|
+
}
|
|
47
|
+
return JSON.stringify({ ok: true, rows })
|
|
48
|
+
} catch (error) {
|
|
49
|
+
if (error && error.code === 'AUTH') return JSON.stringify({ ok: false, code: 'AUTH' })
|
|
50
|
+
const links = Array.from(document.querySelectorAll('a[href*="/chat/"]'))
|
|
51
|
+
const seen = new Set()
|
|
52
|
+
for (const link of links) {
|
|
53
|
+
const match = link.href.match(/\/chat\/([^/?#]+)/)
|
|
54
|
+
if (!match || seen.has(match[1])) continue
|
|
55
|
+
seen.add(match[1])
|
|
56
|
+
rows.push({ provider: 'claude', accountScope: '', id: match[1],
|
|
57
|
+
title: (link.textContent || '').trim() || 'Untitled Claude chat', url: link.href,
|
|
58
|
+
createdAt: '', updatedAt: '', messageCount: 0, cursor: '', partial: true })
|
|
59
|
+
}
|
|
60
|
+
return JSON.stringify({ ok: rows.length > 0, rows, message: String(error && error.message || error) })
|
|
61
|
+
}
|
|
62
|
+
}`
|
|
63
|
+
|
|
64
|
+
const detailScript = String.raw`async function (args) {
|
|
65
|
+
${shared}
|
|
66
|
+
const textOf = value => typeof value === 'string' ? value
|
|
67
|
+
: Array.isArray(value) ? value.map(textOf).filter(Boolean).join('\n')
|
|
68
|
+
: value && typeof value === 'object' ? textOf(value.text || value.content || value.value || value.markdown || '') : ''
|
|
69
|
+
try {
|
|
70
|
+
const org = await organization()
|
|
71
|
+
const url = '/api/organizations/' + encodeURIComponent(org) + '/chat_conversations/' + encodeURIComponent(args.id)
|
|
72
|
+
+ '?tree=True&rendering_mode=messages&render_all_tools=true'
|
|
73
|
+
const response = await fetch(url, { credentials: 'include' })
|
|
74
|
+
if (response.status === 401 || response.status === 403) return JSON.stringify({ ok: false, code: 'AUTH' })
|
|
75
|
+
if (response.status === 429) return JSON.stringify({ ok: false, code: 'RATE_LIMIT' })
|
|
76
|
+
if (!response.ok) throw new Error('detail HTTP ' + response.status)
|
|
77
|
+
const payload = await response.json()
|
|
78
|
+
const messages = payload.chat_messages || payload.messages || (payload.conversation && payload.conversation.chat_messages) || []
|
|
79
|
+
const byId = new Map(messages.map(message => [String(message.uuid || message.id || ''), message]))
|
|
80
|
+
const childIds = new Set(messages.map(message => String(message.parent_message_uuid || message.parent_uuid || message.parent_id || '')).filter(Boolean))
|
|
81
|
+
const requestedLeaf = String(payload.current_leaf_message_uuid || payload.current_message_uuid || payload.current_node_uuid || '')
|
|
82
|
+
let leaf = requestedLeaf && byId.has(requestedLeaf) ? requestedLeaf : ''
|
|
83
|
+
if (!leaf) {
|
|
84
|
+
const leaves = messages.filter(message => !childIds.has(String(message.uuid || message.id || '')))
|
|
85
|
+
leaf = String((leaves[leaves.length - 1] || {}).uuid || (leaves[leaves.length - 1] || {}).id || '')
|
|
86
|
+
}
|
|
87
|
+
const active = new Set()
|
|
88
|
+
for (let id = leaf, guard = 0; id && guard++ < messages.length + 1;) {
|
|
89
|
+
active.add(id)
|
|
90
|
+
const message = byId.get(id)
|
|
91
|
+
id = message ? String(message.parent_message_uuid || message.parent_uuid || message.parent_id || '') : ''
|
|
92
|
+
}
|
|
93
|
+
const ordered = messages.slice().sort((a, b) => String(a.created_at || '').localeCompare(String(b.created_at || '')))
|
|
94
|
+
const rows = ordered.map((message, ordinal) => {
|
|
95
|
+
const id = String(message.uuid || message.id || ordinal)
|
|
96
|
+
const sender = String(message.sender || message.role || '').toLowerCase()
|
|
97
|
+
const content = message.content || message.text || message.content_blocks || ''
|
|
98
|
+
const attachments = (message.attachments || message.files || []).map((file, index) => {
|
|
99
|
+
const candidate = String(file.download_url || file.url || '')
|
|
100
|
+
let locator = ''
|
|
101
|
+
try { if (candidate) { const url = new URL(candidate, location.origin); if (url.origin === location.origin && url.pathname !== '/') locator = url.pathname + url.search } } catch {}
|
|
102
|
+
const name = String(file.name || file.file_name || 'attachment')
|
|
103
|
+
const mimeType = String(file.mime_type || file.mimeType || '')
|
|
104
|
+
return { attachmentId: String(file.id || file.uuid || index), name: String(file.name || file.file_name || 'attachment'),
|
|
105
|
+
kind: mimeType.startsWith('image/') || /\.(?:gif|jpe?g|png|webp)$/i.test(name) ? 'image' : 'file',
|
|
106
|
+
mimeType, size: Number(file.size || 0),
|
|
107
|
+
locator, status: locator ? 'available' : 'unavailable' }
|
|
108
|
+
})
|
|
109
|
+
return { conversationId: args.id, ordinal, messageId: id,
|
|
110
|
+
parentId: String(message.parent_message_uuid || message.parent_uuid || message.parent_id || ''),
|
|
111
|
+
branchId: String(message.branch_uuid || ''), activeBranch: active.size ? active.has(id) : true,
|
|
112
|
+
role: /assistant|claude|model/.test(sender) ? 'assistant' : 'user', text: textOf(content),
|
|
113
|
+
createdAt: String(message.created_at || message.createdAt || ''), attachmentsJson: JSON.stringify(attachments), partial: false }
|
|
114
|
+
}).filter(row => row.text || row.attachmentsJson !== '[]')
|
|
115
|
+
return JSON.stringify({ ok: rows.length > 0, rows })
|
|
116
|
+
} catch (error) {
|
|
117
|
+
if (error && error.code === 'AUTH') return JSON.stringify({ ok: false, code: 'AUTH' })
|
|
118
|
+
return JSON.stringify({ ok: false, message: String(error && error.message || error) })
|
|
119
|
+
}
|
|
120
|
+
}`
|
|
121
|
+
|
|
122
|
+
export const whoamiScript = String.raw`async function () {
|
|
123
|
+
const response = await fetch('/api/account', { credentials: 'include', headers: { Accept: 'application/json' } })
|
|
124
|
+
if (response.status === 401 || response.status === 403) return JSON.stringify({ ok: false, code: 'AUTH' })
|
|
125
|
+
if (response.status === 429) return JSON.stringify({ ok: false, code: 'RATE_LIMIT' })
|
|
126
|
+
if (!response.ok) return JSON.stringify({ ok: false, message: 'account HTTP ' + response.status })
|
|
127
|
+
const payload = await response.json()
|
|
128
|
+
const identity = typeof payload.email_address === 'string' ? payload.email_address.trim() : ''
|
|
129
|
+
if (!identity) return JSON.stringify({ ok: false, message: 'Claude stable account identity unavailable' })
|
|
130
|
+
return JSON.stringify({ ok: true, identity })
|
|
131
|
+
}`
|
|
132
|
+
|
|
133
|
+
registerProvider({
|
|
134
|
+
site: 'dsh-claude', provider: 'Claude', domain: 'claude.ai', home: 'https://claude.ai/',
|
|
135
|
+
conversationUrl: id => `https://claude.ai/chat/${encodeURIComponent(id)}`,
|
|
136
|
+
whoamiScript,
|
|
137
|
+
historyScript, detailScript, fallbackScript: domFallbackScript,
|
|
138
|
+
})
|