dsh-reference-anything 0.4.2 → 0.4.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.
- package/README.md +7 -5
- package/images/logo-icon.png +0 -0
- package/images/logo-mono.png +0 -0
- package/lib/client.js +3781 -1123
- package/lib/contract.d.ts +3 -0
- package/lib/contract.js +2 -1
- package/lib/host.d.ts +8 -2
- package/lib/host.js +3 -2
- package/lib/index.js +0 -2
- package/lib/opencli.d.ts +3 -0
- package/lib/opencli.js +61 -8
- package/lib/reference.js +1 -2
- package/lib/sources/web-chat/index.d.ts +1 -0
- package/lib/sources/web-chat/index.js +21 -1
- package/lib/types.d.ts +5 -1
- package/lib/web.js +4 -5
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/opencli-plugin/common.js +22 -6
- package/package.json +69 -51
package/lib/contract.d.ts
CHANGED
|
@@ -114,6 +114,8 @@ export declare const healthSchema: z.ZodReadonly<z.ZodObject<{
|
|
|
114
114
|
pluginVersion: z.ZodOptional<z.ZodString>;
|
|
115
115
|
adapterCommandsReady: z.ZodBoolean;
|
|
116
116
|
adapterCompatible: z.ZodBoolean;
|
|
117
|
+
latestVersion: z.ZodOptional<z.ZodString>;
|
|
118
|
+
updateAvailable: z.ZodBoolean;
|
|
117
119
|
versionError: z.ZodOptional<z.ZodString>;
|
|
118
120
|
daemonError: z.ZodOptional<z.ZodString>;
|
|
119
121
|
pluginError: z.ZodOptional<z.ZodString>;
|
|
@@ -305,6 +307,7 @@ export declare const deleteInputSchema: z.ZodReadonly<z.ZodObject<{
|
|
|
305
307
|
uriId: z.ZodString;
|
|
306
308
|
}, z.core.$strip>>;
|
|
307
309
|
export declare const storageStatsSchema: z.ZodReadonly<z.ZodObject<{
|
|
310
|
+
systemTempDirectory: z.ZodOptional<z.ZodString>;
|
|
308
311
|
bytes: z.ZodNumber;
|
|
309
312
|
conversations: z.ZodNumber;
|
|
310
313
|
remoteMissing: z.ZodDefault<z.ZodNumber>;
|
package/lib/contract.js
CHANGED
|
@@ -41,7 +41,7 @@ export const healthSchema = z.object({
|
|
|
41
41
|
daemonRunning: z.boolean(), extensionConnected: z.boolean(), extensionState: extensionStateSchema,
|
|
42
42
|
extensionVersion: z.string().optional(), profileCount: z.number().int().nonnegative().optional(),
|
|
43
43
|
opencliCompatible: z.boolean(), daemonVersion: z.string().optional(), daemonStale: z.boolean(),
|
|
44
|
-
connectivityOk: z.boolean(), connectivityChecked: z.boolean(), pluginVersion: z.string().optional(), adapterCommandsReady: z.boolean(), adapterCompatible: z.boolean(),
|
|
44
|
+
connectivityOk: z.boolean(), connectivityChecked: z.boolean(), pluginVersion: z.string().optional(), adapterCommandsReady: z.boolean(), adapterCompatible: z.boolean(), latestVersion: z.string().optional(), updateAvailable: z.boolean(),
|
|
45
45
|
versionError: z.string().optional(), daemonError: z.string().optional(), pluginError: z.string().optional(), doctorError: z.string().optional(),
|
|
46
46
|
}).readonly();
|
|
47
47
|
export const browserProfileSchema = z.object({ id: z.string(), alias: z.string().optional(), connected: z.boolean(), isDefault: z.boolean() }).readonly();
|
|
@@ -84,6 +84,7 @@ export const browsePageSchema = z.object({
|
|
|
84
84
|
}).readonly();
|
|
85
85
|
export const deleteInputSchema = z.object({ uriId: z.string().min(1) }).readonly();
|
|
86
86
|
export const storageStatsSchema = z.object({
|
|
87
|
+
systemTempDirectory: z.string().optional(),
|
|
87
88
|
bytes: z.number().int().nonnegative(), conversations: z.number().int().nonnegative(),
|
|
88
89
|
remoteMissing: z.number().int().nonnegative().default(0), oldAccountConversations: z.number().int().nonnegative().default(0),
|
|
89
90
|
}).readonly();
|
package/lib/host.d.ts
CHANGED
|
@@ -67,7 +67,7 @@ export declare class ReferenceAnythingRemote extends TypertRemoteService {
|
|
|
67
67
|
syncStart(input: {
|
|
68
68
|
providers: ChatProvider[];
|
|
69
69
|
mode: SyncMode;
|
|
70
|
-
}): string
|
|
70
|
+
}): Promise<string>;
|
|
71
71
|
syncStatus(input: {
|
|
72
72
|
jobId: string;
|
|
73
73
|
}): import("./sync/index.ts").SyncJobStatus | undefined;
|
|
@@ -150,7 +150,13 @@ export declare class ReferenceAnythingRemote extends TypertRemoteService {
|
|
|
150
150
|
deleteConversation(input: {
|
|
151
151
|
uriId: string;
|
|
152
152
|
}, signal: AbortSignal): Promise<boolean>;
|
|
153
|
-
storageStats():
|
|
153
|
+
storageStats(): {
|
|
154
|
+
systemTempDirectory: string;
|
|
155
|
+
bytes: number;
|
|
156
|
+
conversations: number;
|
|
157
|
+
remoteMissing: number;
|
|
158
|
+
oldAccountConversations: number;
|
|
159
|
+
};
|
|
154
160
|
clearProvider(input: {
|
|
155
161
|
provider: ChatProvider;
|
|
156
162
|
}, signal: AbortSignal): Promise<number>;
|
package/lib/host.js
CHANGED
|
@@ -75,7 +75,8 @@ export class ReferenceAnythingRemote extends TypertRemoteService {
|
|
|
75
75
|
checkUpdate(signal) { return this.ctx.referenceChatHistory.checkUpdate(signal); }
|
|
76
76
|
installUpdate(signal) { return this.ctx.referenceChatHistory.installUpdate(signal); }
|
|
77
77
|
stats() { return this.ctx.referenceChatHistory.stats(); }
|
|
78
|
-
syncStart(input) {
|
|
78
|
+
async syncStart(input) {
|
|
79
|
+
await this.ctx.referenceChatHistory.ensureBrowser();
|
|
79
80
|
return this.ctx.referenceChatHistory.sync.start(input.providers, input.mode);
|
|
80
81
|
}
|
|
81
82
|
syncStatus(input) { return this.ctx.referenceChatHistory.sync.status(input.jobId); }
|
|
@@ -107,7 +108,7 @@ export class ReferenceAnythingRemote extends TypertRemoteService {
|
|
|
107
108
|
signal.throwIfAborted();
|
|
108
109
|
return this.ctx.referenceChatHistory.remove(input.uriId);
|
|
109
110
|
}
|
|
110
|
-
storageStats() { return this.ctx.referenceChatHistory.storageStats(); }
|
|
111
|
+
storageStats() { return { ...this.ctx.referenceChatHistory.storageStats(), systemTempDirectory: tmpdir() }; }
|
|
111
112
|
clearProvider(input, signal) {
|
|
112
113
|
signal.throwIfAborted();
|
|
113
114
|
return this.ctx.referenceChatHistory.removeProvider(input.provider);
|
package/lib/index.js
CHANGED
|
@@ -79,8 +79,6 @@ export default class ReferenceRuntime extends Service {
|
|
|
79
79
|
static grantKey(ref) { return `${ref.source}\u0000${ref.id}`; }
|
|
80
80
|
static contentMentions(blocks, key) {
|
|
81
81
|
return blocks.some(block => {
|
|
82
|
-
if (block.type === 'tool-result')
|
|
83
|
-
return ReferenceRuntime.contentMentions(block.content, key);
|
|
84
82
|
if (block.type !== 'text' || !mayContainReference(block.text))
|
|
85
83
|
return false;
|
|
86
84
|
try {
|
package/lib/opencli.d.ts
CHANGED
|
@@ -38,6 +38,8 @@ export interface OpenCliHealth {
|
|
|
38
38
|
pluginVersion?: string;
|
|
39
39
|
adapterCommandsReady: boolean;
|
|
40
40
|
adapterCompatible: boolean;
|
|
41
|
+
latestVersion?: string;
|
|
42
|
+
updateAvailable: boolean;
|
|
41
43
|
versionError?: string;
|
|
42
44
|
daemonError?: string;
|
|
43
45
|
pluginError?: string;
|
|
@@ -107,6 +109,7 @@ export declare class OpenCliRunner {
|
|
|
107
109
|
/** Confirm the executable also exposes OpenCLI's plugin command, not merely a semver-looking --version. */
|
|
108
110
|
verifyInstallation(signal?: AbortSignal): Promise<void>;
|
|
109
111
|
profiles(signal?: AbortSignal): Promise<BrowserProfile[]>;
|
|
112
|
+
ensureBrowser(signal?: AbortSignal): Promise<void>;
|
|
110
113
|
installPlugin(pluginUrl: string, signal?: AbortSignal): Promise<void>;
|
|
111
114
|
restartDaemon(signal?: AbortSignal): Promise<void>;
|
|
112
115
|
private probe;
|
package/lib/opencli.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { execFile as nodeExecFile } from 'node:child_process';
|
|
2
2
|
import { existsSync } from 'node:fs';
|
|
3
|
-
import { dirname, join, resolve } from 'node:path';
|
|
3
|
+
import { delimiter, dirname, join, resolve } from 'node:path';
|
|
4
4
|
import { promisify } from 'node:util';
|
|
5
|
+
import { spawn } from 'node:child_process';
|
|
5
6
|
import { createHash } from 'node:crypto';
|
|
6
7
|
const execFile = promisify(nodeExecFile);
|
|
7
8
|
export const MIN_OPENCLI_VERSION = '1.8.6';
|
|
@@ -124,9 +125,10 @@ export class OpenCliRunner {
|
|
|
124
125
|
return this.inspectHealth(false, signal);
|
|
125
126
|
}
|
|
126
127
|
async inspectHealth(checkConnectivity, signal) {
|
|
127
|
-
const [version, daemon, plugins, doctor] = await Promise.all([
|
|
128
|
+
const [version, daemon, plugins, doctor, latest] = await Promise.all([
|
|
128
129
|
this.probe(['--version'], signal), this.probe(['daemon', 'status'], signal), this.probe(['plugin', 'list'], signal),
|
|
129
130
|
checkConnectivity ? this.probe(['doctor'], signal) : Promise.resolve({ value: '', diagnostic: '' }),
|
|
131
|
+
latestOpenCliVersion(signal),
|
|
130
132
|
]);
|
|
131
133
|
const status = parseDaemonStatus(daemon.value);
|
|
132
134
|
const cliVersion = normalizeVersion(version.value);
|
|
@@ -149,6 +151,8 @@ export class OpenCliRunner {
|
|
|
149
151
|
...(pluginVersion ? { pluginVersion: normalizeVersion(pluginVersion) } : {}),
|
|
150
152
|
adapterCommandsReady,
|
|
151
153
|
adapterCompatible: pluginInstalled && adapterCommandsReady && versionAtLeast(pluginVersion ?? '', MIN_ADAPTER_VERSION),
|
|
154
|
+
...(latest.value.trim() ? { latestVersion: normalizeVersion(latest.value) } : {}),
|
|
155
|
+
updateAvailable: Boolean(latest.value.trim() && versionAtLeast(normalizeVersion(latest.value), cliVersion) && normalizeVersion(latest.value) !== cliVersion),
|
|
152
156
|
...(version.error ? { versionError: version.error } : {}),
|
|
153
157
|
...(daemon.error ? { daemonError: daemon.error } : {}),
|
|
154
158
|
...(plugins.error || adapterLoadError ? { pluginError: plugins.error || adapterLoadError } : {}),
|
|
@@ -171,6 +175,22 @@ export class OpenCliRunner {
|
|
|
171
175
|
connected: match[3] === 'connected' && (disconnected < 0 || position < disconnected), isDefault: /\sdefault\s+—/.test(line) }];
|
|
172
176
|
});
|
|
173
177
|
}
|
|
178
|
+
async ensureBrowser(signal) {
|
|
179
|
+
if ((await this.profiles(signal)).some(profile => profile.connected))
|
|
180
|
+
return;
|
|
181
|
+
const child = process.platform === 'win32'
|
|
182
|
+
? spawn('cmd.exe', ['/c', 'start', '', 'msedge.exe', 'about:blank'], { detached: true, stdio: 'ignore', windowsHide: true })
|
|
183
|
+
: process.platform === 'darwin'
|
|
184
|
+
? spawn('open', ['-a', 'Google Chrome', 'about:blank'], { detached: true, stdio: 'ignore' })
|
|
185
|
+
: spawn('xdg-open', ['about:blank'], { detached: true, stdio: 'ignore' });
|
|
186
|
+
child.unref();
|
|
187
|
+
for (let i = 0; i < 20; i++) {
|
|
188
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
189
|
+
if ((await this.profiles(signal)).some(profile => profile.connected))
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
throw new OpenCliError('Browser started, but the OpenCLI extension did not connect', 'EXTENSION_NOT_CONNECTED');
|
|
193
|
+
}
|
|
174
194
|
async installPlugin(pluginUrl, signal) {
|
|
175
195
|
const before = await this.command(['plugin', 'list'], signal);
|
|
176
196
|
if (new RegExp(`\\b${ADAPTER_PLUGIN_NAME}\\b`, 'i').test(before.stdout)) {
|
|
@@ -259,6 +279,18 @@ export class OpenCliRunner {
|
|
|
259
279
|
}
|
|
260
280
|
}
|
|
261
281
|
}
|
|
282
|
+
async function latestOpenCliVersion(signal) {
|
|
283
|
+
const npm = resolveNpmInvocation();
|
|
284
|
+
if (!npm)
|
|
285
|
+
return { value: '', diagnostic: '' };
|
|
286
|
+
try {
|
|
287
|
+
const result = await execFile(npm.file, [...npm.prefix, 'view', OPENCLI_NPM_PACKAGE, 'version'], { encoding: 'utf8', timeout: 15_000, signal });
|
|
288
|
+
return { value: String(result.stdout).trim(), diagnostic: '' };
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
return { value: '', diagnostic: '' };
|
|
292
|
+
}
|
|
293
|
+
}
|
|
262
294
|
/** Keep successful-process diagnostics: OpenCLI reports plugin import failures on stderr while exiting zero. */
|
|
263
295
|
function adapterPluginLoadError(diagnostic = '') {
|
|
264
296
|
const lines = diagnostic.split(/\r?\n/)
|
|
@@ -323,19 +355,40 @@ function openCliCandidates(configured) {
|
|
|
323
355
|
return [...new Set(candidates.filter(Boolean))];
|
|
324
356
|
}
|
|
325
357
|
function resolveNpmInvocation() {
|
|
358
|
+
const node = resolveNodeExecutable();
|
|
326
359
|
const npmExecPath = process.env.npm_execpath;
|
|
327
360
|
if (npmExecPath && existsSync(npmExecPath)) {
|
|
328
361
|
return /\.(?:c?js|mjs)$/i.test(npmExecPath)
|
|
329
|
-
? { file:
|
|
362
|
+
? { file: node, prefix: [npmExecPath] }
|
|
330
363
|
: { file: npmExecPath, prefix: [] };
|
|
331
364
|
}
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
|
|
365
|
+
const npmEntries = [
|
|
366
|
+
join(dirname(node), 'node_modules', 'npm', 'bin', 'npm-cli.js'),
|
|
367
|
+
join(dirname(node), '..', 'node_modules', 'npm', 'bin', 'npm-cli.js'),
|
|
368
|
+
];
|
|
369
|
+
for (const entry of npmEntries)
|
|
370
|
+
if (existsSync(entry))
|
|
371
|
+
return { file: node, prefix: [entry] };
|
|
335
372
|
if (process.platform !== 'win32')
|
|
336
373
|
return { file: 'npm', prefix: [] };
|
|
337
374
|
return undefined;
|
|
338
375
|
}
|
|
376
|
+
/** Electron Node mode still advertises Electron, so CLI parsers misread argv. */
|
|
377
|
+
function resolveNodeExecutable(shimDirectory) {
|
|
378
|
+
if (!process.versions.electron)
|
|
379
|
+
return process.execPath;
|
|
380
|
+
const binary = process.platform === 'win32' ? 'node.exe' : 'node';
|
|
381
|
+
const resources = process.platform === 'darwin'
|
|
382
|
+
? resolve(dirname(process.execPath), '..', 'Resources')
|
|
383
|
+
: join(dirname(process.execPath), 'resources');
|
|
384
|
+
const candidates = [
|
|
385
|
+
...(shimDirectory ? [join(shimDirectory, binary)] : []),
|
|
386
|
+
// Official Desktop ships a standalone dependency runtime as well as Electron.
|
|
387
|
+
join(resources, 'runtime', 'primary-runtime', 'dependencies', 'node', 'bin', binary),
|
|
388
|
+
...(process.env.PATH ?? '').split(delimiter).filter(Boolean).map(path => join(path.replace(/^"|"$/g, ''), binary)),
|
|
389
|
+
];
|
|
390
|
+
return candidates.find(candidate => existsSync(candidate) && resolve(candidate) !== resolve(process.execPath)) ?? 'node';
|
|
391
|
+
}
|
|
339
392
|
function normalizeVersion(value) { return value.trim().replace(/^v/i, '').split(/\s+/)[0] ?? ''; }
|
|
340
393
|
/** Numeric semver comparison for the stable x.y.z versions OpenCLI publishes. */
|
|
341
394
|
export function versionAtLeast(value, minimum) {
|
|
@@ -357,12 +410,12 @@ function resolveInvocation(configured) {
|
|
|
357
410
|
if (/\.cmd$/i.test(configured) && existsSync(explicit)) {
|
|
358
411
|
const entry = join(explicit, '..', 'node_modules', '@jackwener', 'opencli', 'dist', 'src', 'main.js');
|
|
359
412
|
if (existsSync(entry))
|
|
360
|
-
return { file:
|
|
413
|
+
return { file: resolveNodeExecutable(dirname(explicit)), prefix: [entry] };
|
|
361
414
|
}
|
|
362
415
|
if (process.platform === 'win32' && configured === 'opencli') {
|
|
363
416
|
const entry = process.env.APPDATA && join(process.env.APPDATA, 'npm', 'node_modules', '@jackwener', 'opencli', 'dist', 'src', 'main.js');
|
|
364
417
|
if (entry && existsSync(entry))
|
|
365
|
-
return { file: process.
|
|
418
|
+
return { file: resolveNodeExecutable(join(process.env.APPDATA, 'npm')), prefix: [entry] };
|
|
366
419
|
}
|
|
367
420
|
return { file: configured, prefix: [] };
|
|
368
421
|
}
|
package/lib/reference.js
CHANGED
|
@@ -158,8 +158,7 @@ function notice(summary) {
|
|
|
158
158
|
text: `A conversation reference in the previous message could not be resolved: ${summary}`,
|
|
159
159
|
}],
|
|
160
160
|
source: {
|
|
161
|
-
kind: '
|
|
162
|
-
plugin: name,
|
|
161
|
+
kind: 'reference-anything',
|
|
163
162
|
form: 'notice',
|
|
164
163
|
summary: boundContextSummary(summary),
|
|
165
164
|
},
|
|
@@ -100,6 +100,7 @@ export default class WebChatHistoryService extends Service implements ReferenceS
|
|
|
100
100
|
health(signal?: AbortSignal): Promise<import("../../opencli.ts").OpenCliHealth>;
|
|
101
101
|
quickHealth(signal?: AbortSignal): Promise<import("../../opencli.ts").OpenCliHealth>;
|
|
102
102
|
profiles(signal?: AbortSignal): Promise<import("../../opencli.ts").BrowserProfile[]>;
|
|
103
|
+
ensureBrowser(signal?: AbortSignal): Promise<void>;
|
|
103
104
|
private runner;
|
|
104
105
|
installAdapter(signal?: AbortSignal): Promise<boolean>;
|
|
105
106
|
private installAdapterFrom;
|
|
@@ -123,6 +123,7 @@ export default class WebChatHistoryService extends Service {
|
|
|
123
123
|
end = decodeLiveCursor(window.cursor, conversationKey);
|
|
124
124
|
let rows;
|
|
125
125
|
try {
|
|
126
|
+
await this.ensureBrowser(signal);
|
|
126
127
|
rows = await this.runner().detail(conversation.provider, conversation.externalId, signal, conversation.accountScope);
|
|
127
128
|
}
|
|
128
129
|
catch (error) {
|
|
@@ -208,7 +209,12 @@ export default class WebChatHistoryService extends Service {
|
|
|
208
209
|
throw new ReferenceAnythingError('wait for the current conversation sync to finish before updating', 'REFERENCE_SYNC_IN_PROGRESS');
|
|
209
210
|
return this.packageUpdates.update(signal);
|
|
210
211
|
}
|
|
211
|
-
async restartDaemon(signal) {
|
|
212
|
+
async restartDaemon(signal) {
|
|
213
|
+
const runner = this.runner();
|
|
214
|
+
await runner.restartDaemon(signal);
|
|
215
|
+
await this.ensureBrowser(signal);
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
212
218
|
async discoverOpenCli(signal) {
|
|
213
219
|
return discoverOpenCli(this.store.settings.opencliPath, signal);
|
|
214
220
|
}
|
|
@@ -267,6 +273,20 @@ export default class WebChatHistoryService extends Service {
|
|
|
267
273
|
return new OpenCliRunner({ executable: settings.opencliPath, profile: '',
|
|
268
274
|
timeoutMs: this.config.timeoutMs, maxStdoutBytes: this.config.maxStdoutBytes }).profiles(signal);
|
|
269
275
|
}
|
|
276
|
+
async ensureBrowser(signal) {
|
|
277
|
+
const settings = this.store.settings;
|
|
278
|
+
const runner = this.runner();
|
|
279
|
+
const connected = await runner.profiles(signal);
|
|
280
|
+
const selected = connected.find(profile => profile.connected);
|
|
281
|
+
if (selected && !settings.profile) {
|
|
282
|
+
await this.store.setSettings({ ...settings, profile: selected.alias || selected.id });
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
await runner.ensureBrowser(signal);
|
|
286
|
+
const after = (await runner.profiles(signal)).find(profile => profile.connected);
|
|
287
|
+
if (after)
|
|
288
|
+
await this.store.setSettings({ ...settings, profile: after.alias || after.id });
|
|
289
|
+
}
|
|
270
290
|
runner() {
|
|
271
291
|
const settings = this.store.settings;
|
|
272
292
|
return new OpenCliRunner({ executable: settings.opencliPath, profile: settings.profile,
|
package/lib/types.d.ts
CHANGED
|
@@ -236,6 +236,10 @@ export interface ReferenceInput {
|
|
|
236
236
|
}
|
|
237
237
|
declare module '@deepseek-ai/dsh-llm' {
|
|
238
238
|
interface MessageSourceMap {
|
|
239
|
-
'reference-anything': ReferenceContextSource
|
|
239
|
+
'reference-anything': ReferenceContextSource | {
|
|
240
|
+
readonly kind: 'reference-anything';
|
|
241
|
+
readonly form: 'notice';
|
|
242
|
+
readonly summary: string;
|
|
243
|
+
};
|
|
240
244
|
}
|
|
241
245
|
}
|
package/lib/web.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { ReferenceAnythingRemote } from "./host.js";
|
|
2
2
|
import { TYPERT_MANIFEST } from "./typert.js";
|
|
3
3
|
export const name = 'reference-anything-web';
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
export const inject = ['typert', 'referenceChatHistory', 'openListManager', 'referenceCloudDrive'];
|
|
4
|
+
// ReferenceAnythingRemote looks up optional sources through ctx.get(). Making
|
|
5
|
+
// cloud drives a required injection blocks all conversation endpoints when
|
|
6
|
+
// that source is disabled or unavailable in the active profile.
|
|
7
|
+
export const inject = ['typert', 'referenceChatHistory', 'openListManager'];
|
|
9
8
|
export function apply(ctx) {
|
|
10
9
|
new ReferenceAnythingRemote(ctx);
|
|
11
10
|
ctx.effect(() => {
|
package/locale/en.json
ADDED
package/locale/zh.json
ADDED
package/opencli-plugin/common.js
CHANGED
|
@@ -138,6 +138,22 @@ async function inTemporaryTab(page, task) {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
async function navigate(page, url, options) {
|
|
142
|
+
let last
|
|
143
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
144
|
+
try { await page.goto(url, options); return } catch (error) {
|
|
145
|
+
last = error
|
|
146
|
+
if (!/Navigation rejected/i.test(String(error?.message || error)) || attempt === 2) throw error
|
|
147
|
+
if (attempt > 0 && typeof page.newTab === 'function' && typeof page.setActivePage === 'function') {
|
|
148
|
+
const pageId = await page.newTab(url).catch(() => undefined)
|
|
149
|
+
if (pageId) { await page.setActivePage(pageId); return }
|
|
150
|
+
}
|
|
151
|
+
await new Promise(resolve => setTimeout(resolve, 250 * (attempt + 1)))
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
throw last
|
|
155
|
+
}
|
|
156
|
+
|
|
141
157
|
export function registerProvider(config) {
|
|
142
158
|
const browserSession = SYNC_BROWSER_SESSION
|
|
143
159
|
|
|
@@ -154,7 +170,7 @@ export function registerProvider(config) {
|
|
|
154
170
|
args: [],
|
|
155
171
|
columns: ['identity'],
|
|
156
172
|
func: async (page) => inTemporaryTab(page, async () => {
|
|
157
|
-
await page
|
|
173
|
+
await navigate(page, config.home, { waitUntil: 'none' })
|
|
158
174
|
const result = await evaluateWhenProviderReady(
|
|
159
175
|
page, config.whoamiScript, {}, `${config.site} whoami`, { accepts: terminalIdentityResult },
|
|
160
176
|
)
|
|
@@ -180,7 +196,7 @@ export function registerProvider(config) {
|
|
|
180
196
|
func: async (page, kwargs) => inTemporaryTab(page, async () => {
|
|
181
197
|
const since = String(kwargs.since || '').trim()
|
|
182
198
|
if (since && Number.isNaN(Date.parse(since))) throw new ArgumentError('since must be an ISO 8601 instant')
|
|
183
|
-
await page
|
|
199
|
+
await navigate(page, config.home, { waitUntil: 'none' })
|
|
184
200
|
const identity = await evaluateWhenProviderReady(
|
|
185
201
|
page, config.whoamiScript, {}, `${config.site} sync-index identity`, { accepts: terminalIdentityResult },
|
|
186
202
|
)
|
|
@@ -217,7 +233,7 @@ export function registerProvider(config) {
|
|
|
217
233
|
func: async (page, kwargs) => inTemporaryTab(page, async () => {
|
|
218
234
|
const since = String(kwargs.since || '').trim()
|
|
219
235
|
if (since && Number.isNaN(Date.parse(since))) throw new ArgumentError('since must be an ISO 8601 instant')
|
|
220
|
-
await page
|
|
236
|
+
await navigate(page, config.home, { waitUntil: 'none' })
|
|
221
237
|
const rows = assertResult(
|
|
222
238
|
await evaluateWhenProviderReady(page, config.historyScript, { since }, `${config.site} history-all`),
|
|
223
239
|
config.domain,
|
|
@@ -245,7 +261,7 @@ export function registerProvider(config) {
|
|
|
245
261
|
func: async (page, kwargs) => inTemporaryTab(page, async () => {
|
|
246
262
|
const id = String(kwargs.id || '').trim()
|
|
247
263
|
if (!id) throw new ArgumentError('id must be a non-empty conversation id')
|
|
248
|
-
await page
|
|
264
|
+
await navigate(page, config.home, { settleMs: 600 })
|
|
249
265
|
const expectedScope = parseExpectedAccountScope(kwargs.accountScope)
|
|
250
266
|
if (expectedScope) {
|
|
251
267
|
const identity = await evaluate(page, config.whoamiScript, {}, `${config.site} detail identity`)
|
|
@@ -257,7 +273,7 @@ export function registerProvider(config) {
|
|
|
257
273
|
}
|
|
258
274
|
let result = await evaluate(page, config.detailScript, { id }, `${config.site} detail`)
|
|
259
275
|
if (result?.ok !== true && result?.code !== 'AUTH' && result?.code !== 'RATE_LIMIT' && config.fallbackScript) {
|
|
260
|
-
await page
|
|
276
|
+
await navigate(page, config.conversationUrl(id), { settleMs: 1800 })
|
|
261
277
|
result = await evaluate(page, config.fallbackScript, { id }, `${config.site} detail fallback`)
|
|
262
278
|
}
|
|
263
279
|
const rows = assertResult(result, config.domain, `${config.site} detail`)
|
|
@@ -291,7 +307,7 @@ export function registerProvider(config) {
|
|
|
291
307
|
if (!Number.isInteger(maxBytes) || maxBytes < 1 || maxBytes > 26_214_400) {
|
|
292
308
|
throw new ArgumentError('maxBytes must be between 1 and 26214400')
|
|
293
309
|
}
|
|
294
|
-
await page
|
|
310
|
+
await navigate(page, config.home, { settleMs: 500 })
|
|
295
311
|
const expectedScope = parseExpectedAccountScope(kwargs.accountScope)
|
|
296
312
|
if (expectedScope) {
|
|
297
313
|
const identity = await evaluateWhenProviderReady(
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-reference-anything",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "Reference
|
|
3
|
+
"version": "0.4.3",
|
|
4
|
+
"description": "Reference files, sessions, commands, skills, and historical external AI chats from the DSH @ menu.",
|
|
5
|
+
"icon": "./images/logo-icon.png",
|
|
5
6
|
"license": "MIT",
|
|
6
7
|
"publishConfig": {
|
|
7
8
|
"access": "public"
|
|
@@ -58,6 +59,8 @@
|
|
|
58
59
|
"types": "./lib/client/index.d.ts",
|
|
59
60
|
"default": "./lib/client.js"
|
|
60
61
|
},
|
|
62
|
+
"./locale/en.json": "./locale/en.json",
|
|
63
|
+
"./locale/zh.json": "./locale/zh.json",
|
|
61
64
|
"./package.json": "./package.json"
|
|
62
65
|
},
|
|
63
66
|
"files": [
|
|
@@ -66,7 +69,10 @@
|
|
|
66
69
|
"opencli-plugin/opencli-plugin.json",
|
|
67
70
|
"opencli-plugin/package.json",
|
|
68
71
|
"cordis.patch.yml",
|
|
72
|
+
"locale/*.json",
|
|
69
73
|
"images/logo.png",
|
|
74
|
+
"images/logo-icon.png",
|
|
75
|
+
"images/logo-mono.png",
|
|
70
76
|
"NOTICE.md",
|
|
71
77
|
"README.md"
|
|
72
78
|
],
|
|
@@ -99,29 +105,30 @@
|
|
|
99
105
|
},
|
|
100
106
|
"peerDependencies": {
|
|
101
107
|
"@deepseek-ai/cordis": ">=4.0.1",
|
|
102
|
-
"@deepseek-ai/dsh-agent": ">=0.
|
|
103
|
-
"@deepseek-ai/dsh-api-remotes": ">=0.
|
|
104
|
-
"@deepseek-ai/dsh-
|
|
105
|
-
"@deepseek-ai/dsh-
|
|
106
|
-
"@deepseek-ai/dsh-client-
|
|
107
|
-
"@deepseek-ai/dsh-
|
|
108
|
-
"@deepseek-ai/dsh-client-store": ">=0.
|
|
109
|
-
"@deepseek-ai/dsh-client-ui-conversation": ">=0.
|
|
110
|
-
"@deepseek-ai/dsh-client-ui-input-trigger": ">=0.
|
|
111
|
-
"@deepseek-ai/dsh-client-ui-
|
|
112
|
-
"@deepseek-ai/dsh-client-ui-
|
|
113
|
-
"@deepseek-ai/dsh-client-ui-
|
|
114
|
-
"@deepseek-ai/dsh-client-ui-
|
|
115
|
-
"@deepseek-ai/dsh-
|
|
116
|
-
"@deepseek-ai/dsh-
|
|
117
|
-
"@deepseek-ai/dsh-
|
|
118
|
-
"@deepseek-ai/dsh-
|
|
119
|
-
"@deepseek-ai/dsh-session
|
|
120
|
-
"@deepseek-ai/dsh-
|
|
121
|
-
"@deepseek-ai/dsh-
|
|
122
|
-
"@deepseek-ai/dsh-
|
|
123
|
-
"@deepseek-ai/dsh-
|
|
124
|
-
"@deepseek-ai/dsh-typert-
|
|
108
|
+
"@deepseek-ai/dsh-agent": ">=0.2.0-rc.2",
|
|
109
|
+
"@deepseek-ai/dsh-api-remotes": ">=0.2.0-rc.2",
|
|
110
|
+
"@deepseek-ai/dsh-api-session-controller": ">=0.2.0-rc.2",
|
|
111
|
+
"@deepseek-ai/dsh-attachment": ">=0.2.0-rc.2",
|
|
112
|
+
"@deepseek-ai/dsh-client-connection": ">=0.2.0-rc.2",
|
|
113
|
+
"@deepseek-ai/dsh-client-locale": ">=0.2.0-rc.2",
|
|
114
|
+
"@deepseek-ai/dsh-client-store": ">=0.2.0-rc.2",
|
|
115
|
+
"@deepseek-ai/dsh-client-ui-conversation": ">=0.2.0-rc.2",
|
|
116
|
+
"@deepseek-ai/dsh-client-ui-input-trigger": ">=0.2.0-rc.2",
|
|
117
|
+
"@deepseek-ai/dsh-client-ui-primitives": ">=0.2.0-rc.2",
|
|
118
|
+
"@deepseek-ai/dsh-client-ui-renderer": ">=0.2.0-rc.2",
|
|
119
|
+
"@deepseek-ai/dsh-client-ui-settings": ">=0.2.0-rc.2",
|
|
120
|
+
"@deepseek-ai/dsh-client-ui-slots": ">=0.2.0-rc.2",
|
|
121
|
+
"@deepseek-ai/dsh-client-ui-workspace": ">=0.2.0-rc.2",
|
|
122
|
+
"@deepseek-ai/dsh-file-reference": ">=0.2.0-rc.2",
|
|
123
|
+
"@deepseek-ai/dsh-llm": ">=0.2.0-rc.2",
|
|
124
|
+
"@deepseek-ai/dsh-output-retention": ">=0.2.0-rc.2",
|
|
125
|
+
"@deepseek-ai/dsh-session": ">=0.2.0-rc.2",
|
|
126
|
+
"@deepseek-ai/dsh-session-reference": ">=0.2.0-rc.2",
|
|
127
|
+
"@deepseek-ai/dsh-settings": ">=0.2.0-rc.2",
|
|
128
|
+
"@deepseek-ai/dsh-storage-domain": ">=0.2.0-rc.2",
|
|
129
|
+
"@deepseek-ai/dsh-tools": ">=0.2.0-rc.2",
|
|
130
|
+
"@deepseek-ai/dsh-typert-protocol": ">=0.2.0-rc.2",
|
|
131
|
+
"@deepseek-ai/dsh-typert-registry": ">=0.2.0-rc.2",
|
|
125
132
|
"react": "^18.2.0"
|
|
126
133
|
},
|
|
127
134
|
"peerDependenciesMeta": {
|
|
@@ -175,44 +182,55 @@
|
|
|
175
182
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
176
183
|
"@lobehub/icons": "^5.16.0",
|
|
177
184
|
"react-markdown": "^10.1.0",
|
|
185
|
+
"sortablejs": "^1.15.7",
|
|
178
186
|
"zod": "^4.4.3"
|
|
179
187
|
},
|
|
180
188
|
"devDependencies": {
|
|
181
189
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
182
|
-
"@deepseek-ai/dsh-agent": "0.
|
|
183
|
-
"@deepseek-ai/dsh-api-remotes": "0.
|
|
184
|
-
"@deepseek-ai/dsh-
|
|
185
|
-
"@deepseek-ai/dsh-
|
|
186
|
-
"@deepseek-ai/dsh-client-
|
|
187
|
-
"@deepseek-ai/dsh-
|
|
188
|
-
"@deepseek-ai/dsh-client-store": "0.
|
|
189
|
-
"@deepseek-ai/dsh-client-ui-conversation": "0.
|
|
190
|
-
"@deepseek-ai/dsh-client-ui-input-trigger": "0.
|
|
191
|
-
"@deepseek-ai/dsh-client-ui-
|
|
192
|
-
"@deepseek-ai/dsh-client-ui-
|
|
193
|
-
"@deepseek-ai/dsh-client-ui-
|
|
194
|
-
"@deepseek-ai/dsh-client-ui-
|
|
195
|
-
"@deepseek-ai/dsh-
|
|
196
|
-
"@deepseek-ai/dsh-
|
|
197
|
-
"@deepseek-ai/dsh-
|
|
198
|
-
"@deepseek-ai/dsh-
|
|
199
|
-
"@deepseek-ai/dsh-session
|
|
200
|
-
"@deepseek-ai/dsh-
|
|
201
|
-
"@deepseek-ai/dsh-
|
|
202
|
-
"@deepseek-ai/dsh-storage
|
|
203
|
-
"@deepseek-ai/dsh-
|
|
204
|
-
"@deepseek-ai/dsh-
|
|
205
|
-
"@deepseek-ai/dsh-
|
|
206
|
-
"@deepseek-ai/dsh-typert-
|
|
190
|
+
"@deepseek-ai/dsh-agent": "0.2.0-rc.2",
|
|
191
|
+
"@deepseek-ai/dsh-api-remotes": "0.2.0-rc.2",
|
|
192
|
+
"@deepseek-ai/dsh-api-session-controller": "0.2.0-rc.2",
|
|
193
|
+
"@deepseek-ai/dsh-attachment": "0.2.0-rc.2",
|
|
194
|
+
"@deepseek-ai/dsh-client-connection": "0.2.0-rc.2",
|
|
195
|
+
"@deepseek-ai/dsh-client-locale": "0.2.0-rc.2",
|
|
196
|
+
"@deepseek-ai/dsh-client-store": "0.2.0-rc.2",
|
|
197
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.2.0-rc.2",
|
|
198
|
+
"@deepseek-ai/dsh-client-ui-input-trigger": "0.2.0-rc.2",
|
|
199
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.2.0-rc.2",
|
|
200
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.2.0-rc.2",
|
|
201
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.2.0-rc.2",
|
|
202
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.2.0-rc.2",
|
|
203
|
+
"@deepseek-ai/dsh-client-ui-workspace": "0.2.0-rc.2",
|
|
204
|
+
"@deepseek-ai/dsh-file-reference": "0.2.0-rc.2",
|
|
205
|
+
"@deepseek-ai/dsh-llm": "0.2.0-rc.2",
|
|
206
|
+
"@deepseek-ai/dsh-output-retention": "0.2.0-rc.2",
|
|
207
|
+
"@deepseek-ai/dsh-session": "0.2.0-rc.2",
|
|
208
|
+
"@deepseek-ai/dsh-session-reference": "0.2.0-rc.2",
|
|
209
|
+
"@deepseek-ai/dsh-settings": "0.2.0-rc.2",
|
|
210
|
+
"@deepseek-ai/dsh-storage": "0.2.0-rc.2",
|
|
211
|
+
"@deepseek-ai/dsh-storage-domain": "0.2.0-rc.2",
|
|
212
|
+
"@deepseek-ai/dsh-system-prompt": "0.2.0-rc.2",
|
|
213
|
+
"@deepseek-ai/dsh-tools": "0.2.0-rc.2",
|
|
214
|
+
"@deepseek-ai/dsh-typert-protocol": "0.2.0-rc.2",
|
|
215
|
+
"@deepseek-ai/dsh-typert-registry": "0.2.0-rc.2",
|
|
216
|
+
"@deepseek-ai/dsh-util-code-language": "0.2.0-rc.2",
|
|
217
|
+
"@deepseek-ai/dsh-util-workspace-path": "0.2.0-rc.2",
|
|
207
218
|
"@jackwener/opencli": "1.8.6",
|
|
219
|
+
"@shikijs/langs": "4.3.1",
|
|
208
220
|
"@types/node": "^22.20.1",
|
|
209
221
|
"@types/react": "^18.2.0",
|
|
210
222
|
"@types/react-dom": "^18.3.7",
|
|
223
|
+
"@types/sortablejs": "^1.15.9",
|
|
224
|
+
"anser": "2.3.5",
|
|
211
225
|
"esbuild": "^0.25.0",
|
|
212
226
|
"jsdom": "^26.1.0",
|
|
227
|
+
"katex": "0.16.47",
|
|
213
228
|
"react": "^18.2.0",
|
|
214
229
|
"react-dom": "^18.2.0",
|
|
230
|
+
"shiki": "4.3.1",
|
|
231
|
+
"simple-icons": "^16.31.0",
|
|
215
232
|
"typescript": "^5.7.0",
|
|
216
|
-
"vitest": "^3.0.0"
|
|
233
|
+
"vitest": "^3.0.0",
|
|
234
|
+
"zustand": "^5.0.15"
|
|
217
235
|
}
|
|
218
236
|
}
|