dsh-reference-anything 0.3.1 → 0.3.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 +52 -25
- package/README.md +334 -285
- package/cordis.patch.yml +89 -18
- package/lib/client.js +13530 -517
- package/lib/contract.d.ts +155 -3
- package/lib/contract.js +68 -4
- package/lib/download-directory.d.ts +18 -0
- package/lib/download-directory.js +55 -0
- package/lib/errors.d.ts +4 -0
- package/lib/host.d.ts +96 -3
- package/lib/host.js +88 -5
- package/lib/index.d.ts +22 -2
- package/lib/index.js +57 -7
- package/lib/opencli.d.ts +5 -3
- package/lib/opencli.js +13 -6
- package/lib/openlist/host.d.ts +157 -0
- package/lib/openlist/host.js +873 -0
- package/lib/openlist/index.d.ts +84 -0
- package/lib/openlist/index.js +507 -0
- package/lib/render.d.ts +12 -7
- package/lib/render.js +27 -21
- package/lib/sources/cloud-drive/cache.d.ts +60 -0
- package/lib/sources/cloud-drive/cache.js +107 -0
- package/lib/sources/cloud-drive/index.d.ts +190 -0
- package/lib/sources/cloud-drive/index.js +526 -0
- package/lib/sources/cloud-drive/providers/http.d.ts +27 -0
- package/lib/sources/cloud-drive/providers/http.js +73 -0
- package/lib/sources/cloud-drive/providers/openlist.d.ts +59 -0
- package/lib/sources/cloud-drive/providers/openlist.js +535 -0
- package/lib/sources/cloud-drive/registry.d.ts +53 -0
- package/lib/sources/cloud-drive/registry.js +101 -0
- package/lib/sources/cloud-drive/types.d.ts +169 -0
- package/lib/sources/cloud-drive/types.js +17 -0
- package/lib/sources/file.d.ts +2 -0
- package/lib/sources/file.js +2 -0
- package/lib/sources/local-agent/adapters/claude-code.d.ts +16 -0
- package/lib/sources/local-agent/adapters/claude-code.js +171 -0
- package/lib/sources/local-agent/adapters/codex.d.ts +20 -0
- package/lib/sources/local-agent/adapters/codex.js +204 -0
- package/lib/sources/local-agent/adapters/cursor.d.ts +23 -0
- package/lib/sources/local-agent/adapters/cursor.js +121 -0
- package/lib/sources/local-agent/adapters/gemini-cli.d.ts +20 -0
- package/lib/sources/local-agent/adapters/gemini-cli.js +141 -0
- package/lib/sources/local-agent/adapters/grokbuild.d.ts +22 -0
- package/lib/sources/local-agent/adapters/grokbuild.js +76 -0
- package/lib/sources/local-agent/adapters/hermes.d.ts +19 -0
- package/lib/sources/local-agent/adapters/hermes.js +85 -0
- package/lib/sources/local-agent/adapters/kimi.d.ts +28 -0
- package/lib/sources/local-agent/adapters/kimi.js +261 -0
- package/lib/sources/local-agent/adapters/openclaw.d.ts +21 -0
- package/lib/sources/local-agent/adapters/openclaw.js +120 -0
- package/lib/sources/local-agent/adapters/opencode.d.ts +44 -0
- package/lib/sources/local-agent/adapters/opencode.js +236 -0
- package/lib/sources/local-agent/adapters/pi.d.ts +26 -0
- package/lib/sources/local-agent/adapters/pi.js +242 -0
- package/lib/sources/local-agent/adapters/qoder.d.ts +19 -0
- package/lib/sources/local-agent/adapters/qoder.js +93 -0
- package/lib/sources/local-agent/adapters/reasonix.d.ts +23 -0
- package/lib/sources/local-agent/adapters/reasonix.js +90 -0
- package/lib/sources/local-agent/adapters/shared.d.ts +163 -0
- package/lib/sources/local-agent/adapters/shared.js +415 -0
- package/lib/sources/local-agent/adapters/sqlite-shared.d.ts +92 -0
- package/lib/sources/local-agent/adapters/sqlite-shared.js +215 -0
- package/lib/sources/local-agent/adapters/zcode.d.ts +41 -0
- package/lib/sources/local-agent/adapters/zcode.js +159 -0
- package/lib/sources/local-agent/index.d.ts +222 -0
- package/lib/sources/local-agent/index.js +656 -0
- package/lib/sources/local-agent/page.d.ts +55 -0
- package/lib/sources/local-agent/page.js +83 -0
- package/lib/sources/local-agent/path.d.ts +8 -0
- package/lib/sources/local-agent/path.js +43 -0
- package/lib/sources/local-agent/registry.d.ts +68 -0
- package/lib/sources/local-agent/registry.js +116 -0
- package/lib/sources/local-agent/scan.d.ts +175 -0
- package/lib/sources/local-agent/scan.js +472 -0
- package/lib/sources/local-agent/sqlite.d.ts +45 -0
- package/lib/sources/local-agent/sqlite.js +113 -0
- package/lib/sources/local-agent/store.d.ts +93 -0
- package/lib/sources/local-agent/store.js +113 -0
- package/lib/sources/local-agent/types.d.ts +338 -0
- package/lib/sources/local-agent/types.js +20 -0
- package/lib/sources/web-chat/index.d.ts +5 -1
- package/lib/sources/web-chat/index.js +47 -8
- package/lib/store/spec.d.ts +50 -0
- package/lib/store/spec.js +2 -2
- package/lib/sync/index.d.ts +1 -0
- package/lib/sync/index.js +28 -8
- package/lib/tool.d.ts +5 -0
- package/lib/tool.js +418 -45
- package/lib/typert.js +13 -1
- package/lib/types.d.ts +28 -2
- package/lib/update.d.ts +6 -0
- package/lib/update.js +29 -1
- package/lib/web.js +5 -1
- package/lib/wire.d.ts +80 -0
- package/lib/wire.js +30 -1
- package/opencli-plugin/chatgpt.js +30 -27
- package/opencli-plugin/claude.js +12 -8
- package/opencli-plugin/common.js +266 -187
- package/opencli-plugin/deepseek.js +8 -5
- package/opencli-plugin/gemini.js +42 -38
- package/opencli-plugin/grok.js +22 -21
- package/opencli-plugin/kimi.js +34 -31
- package/opencli-plugin/opencli-plugin.json +6 -6
- package/opencli-plugin/package.json +8 -8
- package/package.json +200 -185
package/lib/contract.d.ts
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { InvocationDescriptor } from '@deepseek-ai/dsh-typert-protocol';
|
|
3
|
+
/**
|
|
4
|
+
* One local-agent transcript as the `@` menu sees it.
|
|
5
|
+
*
|
|
6
|
+
* `id` is the source-scoped `kind:relPath`, not a `dsh-ref:` URI — the client
|
|
7
|
+
* wraps it, the way it does for web chats, so the `'local-agent'` source string
|
|
8
|
+
* stays hardcoded in exactly one place. Deliberately carries no `origin`: the
|
|
9
|
+
* absolute path adds nothing a menu row can use and everything a screen-share
|
|
10
|
+
* leaks.
|
|
11
|
+
*/
|
|
12
|
+
export declare const agentCandidateSchema: z.ZodReadonly<z.ZodObject<{
|
|
13
|
+
id: z.ZodString;
|
|
14
|
+
kind: z.ZodString;
|
|
15
|
+
label: z.ZodString;
|
|
16
|
+
provider: z.ZodString;
|
|
17
|
+
updatedAt: z.ZodOptional<z.ZodNumber>;
|
|
18
|
+
}, z.core.$strip>>;
|
|
19
|
+
export declare const agentStatsSchema: z.ZodReadonly<z.ZodObject<{
|
|
20
|
+
agent: z.ZodEnum<{
|
|
21
|
+
kimi: "kimi";
|
|
22
|
+
"claude-code": "claude-code";
|
|
23
|
+
codex: "codex";
|
|
24
|
+
cursor: "cursor";
|
|
25
|
+
qoder: "qoder";
|
|
26
|
+
reasonix: "reasonix";
|
|
27
|
+
openclaw: "openclaw";
|
|
28
|
+
grokbuild: "grokbuild";
|
|
29
|
+
hermes: "hermes";
|
|
30
|
+
"gemini-cli": "gemini-cli";
|
|
31
|
+
pi: "pi";
|
|
32
|
+
opencode: "opencode";
|
|
33
|
+
mimocode: "mimocode";
|
|
34
|
+
zcode: "zcode";
|
|
35
|
+
}>;
|
|
36
|
+
conversations: z.ZodNumber;
|
|
37
|
+
}, z.core.$strip>>;
|
|
38
|
+
export declare const driveCandidateSchema: z.ZodReadonly<z.ZodObject<{
|
|
39
|
+
id: z.ZodString;
|
|
40
|
+
label: z.ZodString;
|
|
41
|
+
provider: z.ZodString;
|
|
42
|
+
origin: z.ZodOptional<z.ZodString>;
|
|
43
|
+
updatedAt: z.ZodOptional<z.ZodNumber>;
|
|
44
|
+
searchIncomplete: z.ZodOptional<z.ZodBoolean>;
|
|
45
|
+
isDirectory: z.ZodOptional<z.ZodBoolean>;
|
|
46
|
+
}, z.core.$strict>>;
|
|
3
47
|
export declare const searchInputSchema: z.ZodReadonly<z.ZodObject<{
|
|
4
48
|
query: z.ZodString;
|
|
5
49
|
provider: z.ZodOptional<z.ZodEnum<{
|
|
@@ -92,6 +136,8 @@ export declare const packageUpdateStatusSchema: z.ZodReadonly<z.ZodObject<{
|
|
|
92
136
|
latestVersion: z.ZodString;
|
|
93
137
|
updateAvailable: z.ZodBoolean;
|
|
94
138
|
checkedAt: z.ZodNumber;
|
|
139
|
+
releaseNotes: z.ZodOptional<z.ZodString>;
|
|
140
|
+
releaseUrl: z.ZodOptional<z.ZodString>;
|
|
95
141
|
error: z.ZodOptional<z.ZodString>;
|
|
96
142
|
}, z.core.$strip>>;
|
|
97
143
|
export declare const packageUpdateResultSchema: z.ZodReadonly<z.ZodObject<{
|
|
@@ -274,9 +320,6 @@ export declare const clearProviderInputSchema: z.ZodReadonly<z.ZodObject<{
|
|
|
274
320
|
kimi: "kimi";
|
|
275
321
|
}>;
|
|
276
322
|
}, z.core.$strip>>;
|
|
277
|
-
export declare const clearOlderInputSchema: z.ZodReadonly<z.ZodObject<{
|
|
278
|
-
days: z.ZodNumber;
|
|
279
|
-
}, z.core.$strip>>;
|
|
280
323
|
export declare const providerSyncStateSchema: z.ZodReadonly<z.ZodObject<{
|
|
281
324
|
provider: z.ZodEnum<{
|
|
282
325
|
chatgpt: "chatgpt";
|
|
@@ -296,4 +339,113 @@ export declare const providerSyncStateSchema: z.ZodReadonly<z.ZodObject<{
|
|
|
296
339
|
lastCompleteScanAt: z.ZodString;
|
|
297
340
|
error: z.ZodString;
|
|
298
341
|
}, z.core.$strip>>;
|
|
342
|
+
export declare const openListStatusSchema: z.ZodReadonly<z.ZodObject<{
|
|
343
|
+
state: z.ZodEnum<{
|
|
344
|
+
failed: "failed";
|
|
345
|
+
running: "running";
|
|
346
|
+
install: "install";
|
|
347
|
+
downloading: "downloading";
|
|
348
|
+
upgrade: "upgrade";
|
|
349
|
+
}>;
|
|
350
|
+
installed: z.ZodBoolean;
|
|
351
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
352
|
+
managed: "managed";
|
|
353
|
+
external: "external";
|
|
354
|
+
}>>;
|
|
355
|
+
version: z.ZodOptional<z.ZodString>;
|
|
356
|
+
endpoint: z.ZodOptional<z.ZodString>;
|
|
357
|
+
supportsRollback: z.ZodBoolean;
|
|
358
|
+
upgradeAvailable: z.ZodBoolean;
|
|
359
|
+
newerVersion: z.ZodOptional<z.ZodBoolean>;
|
|
360
|
+
error: z.ZodOptional<z.ZodString>;
|
|
361
|
+
}, z.core.$strict>>;
|
|
362
|
+
export declare const openListDriverFieldSchema: z.ZodReadonly<z.ZodObject<{
|
|
363
|
+
name: z.ZodString;
|
|
364
|
+
label: z.ZodString;
|
|
365
|
+
type: z.ZodEnum<{
|
|
366
|
+
number: "number";
|
|
367
|
+
boolean: "boolean";
|
|
368
|
+
text: "text";
|
|
369
|
+
password: "password";
|
|
370
|
+
select: "select";
|
|
371
|
+
}>;
|
|
372
|
+
secret: z.ZodBoolean;
|
|
373
|
+
required: z.ZodBoolean;
|
|
374
|
+
hasDefault: z.ZodOptional<z.ZodBoolean>;
|
|
375
|
+
default: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
|
|
376
|
+
options: z.ZodOptional<z.ZodArray<z.ZodReadonly<z.ZodObject<{
|
|
377
|
+
label: z.ZodString;
|
|
378
|
+
value: z.ZodString;
|
|
379
|
+
}, z.core.$strip>>>>;
|
|
380
|
+
}, z.core.$strict>>;
|
|
381
|
+
export declare const openListDriverSchema: z.ZodReadonly<z.ZodObject<{
|
|
382
|
+
name: z.ZodString;
|
|
383
|
+
description: z.ZodOptional<z.ZodString>;
|
|
384
|
+
quickAuth: z.ZodBoolean;
|
|
385
|
+
fields: z.ZodArray<z.ZodReadonly<z.ZodObject<{
|
|
386
|
+
name: z.ZodString;
|
|
387
|
+
label: z.ZodString;
|
|
388
|
+
type: z.ZodEnum<{
|
|
389
|
+
number: "number";
|
|
390
|
+
boolean: "boolean";
|
|
391
|
+
text: "text";
|
|
392
|
+
password: "password";
|
|
393
|
+
select: "select";
|
|
394
|
+
}>;
|
|
395
|
+
secret: z.ZodBoolean;
|
|
396
|
+
required: z.ZodBoolean;
|
|
397
|
+
hasDefault: z.ZodOptional<z.ZodBoolean>;
|
|
398
|
+
default: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
|
|
399
|
+
options: z.ZodOptional<z.ZodArray<z.ZodReadonly<z.ZodObject<{
|
|
400
|
+
label: z.ZodString;
|
|
401
|
+
value: z.ZodString;
|
|
402
|
+
}, z.core.$strip>>>>;
|
|
403
|
+
}, z.core.$strict>>>;
|
|
404
|
+
}, z.core.$strict>>;
|
|
405
|
+
export declare const openListMountSchema: z.ZodReadonly<z.ZodObject<{
|
|
406
|
+
id: z.ZodString;
|
|
407
|
+
name: z.ZodString;
|
|
408
|
+
driver: z.ZodString;
|
|
409
|
+
enabled: z.ZodBoolean;
|
|
410
|
+
status: z.ZodOptional<z.ZodEnum<{
|
|
411
|
+
error: "error";
|
|
412
|
+
ready: "ready";
|
|
413
|
+
disabled: "disabled";
|
|
414
|
+
}>>;
|
|
415
|
+
error: z.ZodOptional<z.ZodString>;
|
|
416
|
+
capacityUsed: z.ZodOptional<z.ZodNumber>;
|
|
417
|
+
capacityTotal: z.ZodOptional<z.ZodNumber>;
|
|
418
|
+
indexStatus: z.ZodOptional<z.ZodEnum<{
|
|
419
|
+
complete: "complete";
|
|
420
|
+
failed: "failed";
|
|
421
|
+
running: "running";
|
|
422
|
+
idle: "idle";
|
|
423
|
+
}>>;
|
|
424
|
+
indexProgress: z.ZodOptional<z.ZodNumber>;
|
|
425
|
+
indexCount: z.ZodOptional<z.ZodNumber>;
|
|
426
|
+
}, z.core.$strict>>;
|
|
427
|
+
export declare const openListExternalConnectSchema: z.ZodReadonly<z.ZodObject<{
|
|
428
|
+
endpoint: z.ZodString;
|
|
429
|
+
username: z.ZodOptional<z.ZodString>;
|
|
430
|
+
password: z.ZodOptional<z.ZodString>;
|
|
431
|
+
token: z.ZodOptional<z.ZodString>;
|
|
432
|
+
}, z.core.$strict>>;
|
|
433
|
+
export declare const openListMountCreateSchema: z.ZodReadonly<z.ZodObject<{
|
|
434
|
+
id: z.ZodOptional<z.ZodString>;
|
|
435
|
+
mountPath: z.ZodString;
|
|
436
|
+
driver: z.ZodString;
|
|
437
|
+
addition: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
438
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
439
|
+
remark: z.ZodOptional<z.ZodString>;
|
|
440
|
+
}, z.core.$strict>>;
|
|
441
|
+
export declare const openListMountInputSchema: z.ZodReadonly<z.ZodObject<{
|
|
442
|
+
id: z.ZodString;
|
|
443
|
+
}, z.core.$strict>>;
|
|
444
|
+
export declare const openListDisableMountSchema: z.ZodReadonly<z.ZodObject<{
|
|
445
|
+
id: z.ZodString;
|
|
446
|
+
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
447
|
+
}, z.core.$strict>>;
|
|
448
|
+
export declare const openListUpgradeInputSchema: z.ZodReadonly<z.ZodObject<{
|
|
449
|
+
rollback: z.ZodOptional<z.ZodBoolean>;
|
|
450
|
+
}, z.core.$strict>>;
|
|
299
451
|
export declare const REFERENCE_ANYTHING_INVOCATIONS: readonly InvocationDescriptor[];
|
package/lib/contract.js
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { providerSchema, settingsRecordSchema } from "./wire.js";
|
|
2
|
+
import { localAgentSchema, providerSchema, settingsRecordSchema } from "./wire.js";
|
|
3
|
+
/**
|
|
4
|
+
* One local-agent transcript as the `@` menu sees it.
|
|
5
|
+
*
|
|
6
|
+
* `id` is the source-scoped `kind:relPath`, not a `dsh-ref:` URI — the client
|
|
7
|
+
* wraps it, the way it does for web chats, so the `'local-agent'` source string
|
|
8
|
+
* stays hardcoded in exactly one place. Deliberately carries no `origin`: the
|
|
9
|
+
* absolute path adds nothing a menu row can use and everything a screen-share
|
|
10
|
+
* leaks.
|
|
11
|
+
*/
|
|
12
|
+
export const agentCandidateSchema = z.object({ id: z.string(), kind: z.string(), label: z.string(), provider: z.string(), updatedAt: z.number().optional() }).readonly();
|
|
13
|
+
export const agentStatsSchema = z.object({ agent: localAgentSchema, conversations: z.number().int().nonnegative() }).readonly();
|
|
14
|
+
// `origin` is the drive's own display path, shown under the candidate. It is
|
|
15
|
+
// never a download URL: those are signed with the account's credential and
|
|
16
|
+
// must not cross this wire.
|
|
17
|
+
export const driveCandidateSchema = z.object({
|
|
18
|
+
id: z.string(), label: z.string(), provider: z.string(),
|
|
19
|
+
origin: z.string().optional(), updatedAt: z.number().optional(),
|
|
20
|
+
searchIncomplete: z.boolean().optional(), isDirectory: z.boolean().optional(),
|
|
21
|
+
}).strict().readonly();
|
|
22
|
+
/**
|
|
23
|
+
* Binds the calling session to the invocation, so the Host can scope a search
|
|
24
|
+
* to the session's cwd. Reintroduced here after 0.3.0 handed file and session
|
|
25
|
+
* lookup back to DSH's native Remotes and removed its last other caller.
|
|
26
|
+
*/
|
|
27
|
+
const agentLookup = { name: 'agent', wire: 'agentId', source: 'lookup', lookup: 'agent',
|
|
28
|
+
codec: { mode: 'strict', typeSymbol: '@deepseek-ai/dsh-session/types#SessionId', schema: z.string().min(1) } };
|
|
3
29
|
export const searchInputSchema = z.object({
|
|
4
30
|
query: z.string(), provider: providerSchema.optional(), limit: z.number().int().min(1).max(100),
|
|
5
31
|
}).readonly();
|
|
@@ -24,7 +50,7 @@ export const openCliDiscoverySchema = z.object({
|
|
|
24
50
|
}).readonly();
|
|
25
51
|
export const packageUpdateStatusSchema = z.object({
|
|
26
52
|
currentVersion: z.string(), latestVersion: z.string(), updateAvailable: z.boolean(),
|
|
27
|
-
checkedAt: z.number().int().nonnegative(), error: z.string().optional(),
|
|
53
|
+
checkedAt: z.number().int().nonnegative(), releaseNotes: z.string().max(12_000).optional(), releaseUrl: z.string().url().optional(), error: z.string().optional(),
|
|
28
54
|
}).readonly();
|
|
29
55
|
export const packageUpdateResultSchema = z.object({
|
|
30
56
|
version: z.string(), restartRequired: z.boolean(),
|
|
@@ -62,12 +88,39 @@ export const storageStatsSchema = z.object({
|
|
|
62
88
|
remoteMissing: z.number().int().nonnegative().default(0), oldAccountConversations: z.number().int().nonnegative().default(0),
|
|
63
89
|
}).readonly();
|
|
64
90
|
export const clearProviderInputSchema = z.object({ provider: providerSchema }).readonly();
|
|
65
|
-
export const clearOlderInputSchema = z.object({ days: z.number().int().min(1).max(36500) }).readonly();
|
|
66
91
|
export const providerSyncStateSchema = z.object({
|
|
67
92
|
provider: providerSchema, status: z.enum(['idle', 'running', 'cancelled', 'failed']),
|
|
68
93
|
lastSyncAt: z.string(), lastCompleteScanAt: z.string(), error: z.string(),
|
|
69
94
|
}).readonly();
|
|
95
|
+
// OpenList wire DTOs intentionally omit every credential, storage addition,
|
|
96
|
+
// raw/signed URL, and server-supplied diagnostic. The Host keeps those in its
|
|
97
|
+
// restricted credential file and translates failures to a generic message.
|
|
98
|
+
export const openListStatusSchema = z.object({
|
|
99
|
+
state: z.enum(['install', 'downloading', 'running', 'failed', 'upgrade']), installed: z.boolean(),
|
|
100
|
+
mode: z.enum(['managed', 'external']).optional(), version: z.string().optional(), endpoint: z.string().optional(),
|
|
101
|
+
supportsRollback: z.boolean(), upgradeAvailable: z.boolean(), newerVersion: z.boolean().optional(), error: z.string().optional(),
|
|
102
|
+
}).strict().readonly();
|
|
103
|
+
export const openListDriverFieldSchema = z.object({
|
|
104
|
+
name: z.string(), label: z.string(), type: z.enum(['text', 'password', 'number', 'boolean', 'select']), secret: z.boolean(), required: z.boolean(), hasDefault: z.boolean().optional(), default: z.union([z.string(), z.number(), z.boolean()]).optional(),
|
|
105
|
+
options: z.array(z.object({ label: z.string(), value: z.string() }).readonly()).optional(),
|
|
106
|
+
}).strict().readonly();
|
|
107
|
+
export const openListDriverSchema = z.object({ name: z.string(), description: z.string().optional(), quickAuth: z.boolean(), fields: z.array(openListDriverFieldSchema) }).strict().readonly();
|
|
108
|
+
export const openListMountSchema = z.object({
|
|
109
|
+
id: z.string(), name: z.string(), driver: z.string(), enabled: z.boolean(), status: z.enum(['ready', 'disabled', 'error']).optional(), error: z.string().optional(),
|
|
110
|
+
capacityUsed: z.number().nonnegative().optional(), capacityTotal: z.number().nonnegative().optional(),
|
|
111
|
+
indexStatus: z.enum(['idle', 'running', 'complete', 'failed']).optional(), indexProgress: z.number().min(0).max(1).optional(), indexCount: z.number().nonnegative().optional(),
|
|
112
|
+
}).strict().readonly();
|
|
113
|
+
export const openListExternalConnectSchema = z.object({ endpoint: z.string().min(1), username: z.string().optional(), password: z.string().optional(), token: z.string().optional() }).strict().readonly();
|
|
114
|
+
export const openListMountCreateSchema = z.object({ id: z.string().min(1).optional(), mountPath: z.string().min(1), driver: z.string().min(1), addition: z.record(z.string(), z.unknown()), order: z.number().int().optional(), remark: z.string().optional() }).strict().readonly();
|
|
115
|
+
export const openListMountInputSchema = z.object({ id: z.string().min(1) }).strict().readonly();
|
|
116
|
+
export const openListDisableMountSchema = z.object({ id: z.string().min(1), disabled: z.boolean().optional() }).strict().readonly();
|
|
117
|
+
export const openListUpgradeInputSchema = z.object({ rollback: z.boolean().optional() }).strict().readonly();
|
|
70
118
|
export const REFERENCE_ANYTHING_INVOCATIONS = [
|
|
119
|
+
descriptor('agentSearch', [agentLookup, { name: 'input', wire: 'input', source: 'json', codec: strict('AgentSearchInput', z.object({ query: z.string(), limit: z.number().int().min(1).max(100) }).readonly()) }], strict('AgentCandidate[]', z.array(agentCandidateSchema)), true),
|
|
120
|
+
descriptor('agentStats', [], strict('AgentStats[]', z.array(agentStatsSchema)), true),
|
|
121
|
+
// No session lookup, unlike `agentSearch`: a drive is the same drive from
|
|
122
|
+
// every workspace, so there is nothing to scope the query to.
|
|
123
|
+
descriptor('driveSearch', [{ name: 'input', wire: 'input', source: 'json', codec: strict('DriveSearchInput', z.object({ query: z.string(), limit: z.number().int().min(1).max(100) }).readonly()) }], strict('DriveCandidate[]', z.array(driveCandidateSchema)), true),
|
|
71
124
|
descriptor('search', [{ name: 'input', wire: 'input', source: 'json', codec: strict('SearchInput', searchInputSchema) }], strict('SearchResult[]', z.array(searchResultSchema)), true),
|
|
72
125
|
descriptor('health', [], strict('Health', healthSchema), true),
|
|
73
126
|
descriptor('quickHealth', [], strict('Health', healthSchema), true),
|
|
@@ -85,14 +138,25 @@ export const REFERENCE_ANYTHING_INVOCATIONS = [
|
|
|
85
138
|
descriptor('syncCancel', [{ name: 'input', wire: 'input', source: 'json', codec: strict('JobInput', jobInputSchema) }], strict('Boolean', z.boolean())),
|
|
86
139
|
descriptor('settingsGet', [], strict('Settings', settingsRecordSchema)),
|
|
87
140
|
descriptor('settingsUpdate', [{ name: 'settings', wire: 'settings', source: 'json', codec: strict('Settings', settingsRecordSchema) }], strict('Settings', settingsRecordSchema)),
|
|
141
|
+
descriptor('openDownloadDirectory', [], strict('Boolean', z.boolean()), true),
|
|
88
142
|
descriptor('browse', [{ name: 'input', wire: 'input', source: 'json', codec: strict('BrowseInput', browseInputSchema) }], strict('BrowsePage', browsePageSchema), true),
|
|
89
143
|
descriptor('deleteConversation', [{ name: 'input', wire: 'input', source: 'json', codec: strict('DeleteInput', deleteInputSchema) }], strict('Boolean', z.boolean()), true),
|
|
90
144
|
descriptor('storageStats', [], strict('StorageStats', storageStatsSchema)),
|
|
91
145
|
descriptor('clearProvider', [{ name: 'input', wire: 'input', source: 'json', codec: strict('ClearProviderInput', clearProviderInputSchema) }], strict('Count', z.number().int().nonnegative()), true),
|
|
92
|
-
descriptor('clearOlder', [{ name: 'input', wire: 'input', source: 'json', codec: strict('ClearOlderInput', clearOlderInputSchema) }], strict('Count', z.number().int().nonnegative()), true),
|
|
93
146
|
descriptor('clearRemoteMissing', [], strict('Count', z.number().int().nonnegative()), true),
|
|
94
147
|
descriptor('clearOldAccounts', [], strict('Count', z.number().int().nonnegative()), true),
|
|
95
148
|
descriptor('syncStates', [], strict('ProviderSyncState[]', z.array(providerSyncStateSchema))),
|
|
149
|
+
descriptor('openListStatus', [], strict('OpenListStatus', openListStatusSchema), true),
|
|
150
|
+
descriptor('openListInstall', [], strict('OpenListStatus', openListStatusSchema), true),
|
|
151
|
+
descriptor('openListUpgrade', [{ name: 'input', wire: 'input', source: 'json', codec: strict('OpenListUpgradeInput', openListUpgradeInputSchema) }], strict('OpenListStatus', openListStatusSchema), true),
|
|
152
|
+
descriptor('openListConnectExternal', [{ name: 'input', wire: 'input', source: 'json', codec: strict('OpenListExternalConnect', openListExternalConnectSchema) }], strict('OpenListStatus', openListStatusSchema), true),
|
|
153
|
+
descriptor('openListDisconnect', [], strict('OpenListStatus', openListStatusSchema), true),
|
|
154
|
+
descriptor('openListDrivers', [], strict('OpenListDriver[]', z.array(openListDriverSchema)), true),
|
|
155
|
+
descriptor('openListMounts', [], strict('OpenListMount[]', z.array(openListMountSchema)), true),
|
|
156
|
+
descriptor('openListCreateMount', [{ name: 'input', wire: 'input', source: 'json', codec: strict('OpenListMountCreate', openListMountCreateSchema) }], strict('OpenListMount', openListMountSchema), true),
|
|
157
|
+
descriptor('openListDisableMount', [{ name: 'input', wire: 'input', source: 'json', codec: strict('OpenListDisableMountInput', openListDisableMountSchema) }], strict('Boolean', z.boolean()), true),
|
|
158
|
+
descriptor('openListRemoveMount', [{ name: 'input', wire: 'input', source: 'json', codec: strict('OpenListMountInput', openListMountInputSchema) }], strict('Boolean', z.boolean()), true),
|
|
159
|
+
descriptor('openListReindex', [{ name: 'input', wire: 'input', source: 'json', codec: strict('OpenListMountInput', openListMountInputSchema) }], strict('OpenListReindex', z.object({ supported: z.boolean(), reason: z.string().optional() }).readonly()), true),
|
|
96
160
|
];
|
|
97
161
|
function strict(type, schema) {
|
|
98
162
|
return { mode: 'strict', typeSymbol: `dsh-reference-anything#${type}`, schema };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unlike `path.isAbsolute`, this excludes Windows paths rooted on the current
|
|
3
|
+
* drive (`\foo`) and drive-relative paths (`C:foo`). Those forms can silently
|
|
4
|
+
* resolve somewhere other than the directory displayed in Settings.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isFullyQualifiedDownloadDirectory(value: string, platform?: NodeJS.Platform): boolean;
|
|
7
|
+
/** Append an mkdtemp prefix without lexically resolving symlinks or `..`. */
|
|
8
|
+
export declare function appendDownloadDirectoryPrefix(directory: string, prefix: string, platform?: NodeJS.Platform): string;
|
|
9
|
+
export interface DownloadDirectoryValidationOptions {
|
|
10
|
+
platform?: NodeJS.Platform;
|
|
11
|
+
lstatPath?: (path: string) => Promise<{
|
|
12
|
+
isDirectory(): boolean;
|
|
13
|
+
isSymbolicLink(): boolean;
|
|
14
|
+
}>;
|
|
15
|
+
accessPath?: (path: string, mode: number) => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
/** Validate the user-selected base without changing its filesystem semantics. */
|
|
18
|
+
export declare function validateDownloadDirectory(value: string, options?: DownloadDirectoryValidationOptions): Promise<string>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { constants } from 'node:fs';
|
|
2
|
+
import { access, lstat } from 'node:fs/promises';
|
|
3
|
+
import { ReferenceAnythingError } from "./errors.js";
|
|
4
|
+
/**
|
|
5
|
+
* Unlike `path.isAbsolute`, this excludes Windows paths rooted on the current
|
|
6
|
+
* drive (`\foo`) and drive-relative paths (`C:foo`). Those forms can silently
|
|
7
|
+
* resolve somewhere other than the directory displayed in Settings.
|
|
8
|
+
*/
|
|
9
|
+
export function isFullyQualifiedDownloadDirectory(value, platform = process.platform) {
|
|
10
|
+
if (platform !== 'win32')
|
|
11
|
+
return value.startsWith('/');
|
|
12
|
+
// Device and NT namespaces bypass ordinary filesystem parsing and can name
|
|
13
|
+
// objects outside the selected volume/share boundary. This feature only
|
|
14
|
+
// accepts conventional DOS drive paths and UNC shares.
|
|
15
|
+
if (/^\\\\[?.][\\/]/.test(value))
|
|
16
|
+
return false;
|
|
17
|
+
if (/^[A-Za-z]:[\\/]/.test(value))
|
|
18
|
+
return true;
|
|
19
|
+
return /^\\\\[^\\/]+[\\/][^\\/]+(?:[\\/].*)?$/.test(value);
|
|
20
|
+
}
|
|
21
|
+
/** Append an mkdtemp prefix without lexically resolving symlinks or `..`. */
|
|
22
|
+
export function appendDownloadDirectoryPrefix(directory, prefix, platform = process.platform) {
|
|
23
|
+
if (!isFullyQualifiedDownloadDirectory(directory, platform) || directory.includes('\0')) {
|
|
24
|
+
throw new ReferenceAnythingError('Cloud-drive download directory is invalid', 'REFERENCE_INVALID_CONFIG');
|
|
25
|
+
}
|
|
26
|
+
if (prefix === '' || prefix === '.' || prefix === '..' || prefix.includes('\0') || /[\\/]/.test(prefix)) {
|
|
27
|
+
throw new ReferenceAnythingError('Cloud-drive temporary-directory prefix is invalid', 'REFERENCE_INVALID_CONFIG');
|
|
28
|
+
}
|
|
29
|
+
const hasSeparator = platform === 'win32' ? /[\\/]$/.test(directory) : directory.endsWith('/');
|
|
30
|
+
return `${directory}${hasSeparator ? '' : platform === 'win32' ? '\\' : '/'}${prefix}`;
|
|
31
|
+
}
|
|
32
|
+
/** Validate the user-selected base without changing its filesystem semantics. */
|
|
33
|
+
export async function validateDownloadDirectory(value, options = {}) {
|
|
34
|
+
if (value === '')
|
|
35
|
+
return '';
|
|
36
|
+
const platform = options.platform ?? process.platform;
|
|
37
|
+
if (value.includes('\0') || !isFullyQualifiedDownloadDirectory(value, platform)) {
|
|
38
|
+
throw new ReferenceAnythingError('Cloud-drive download directory must be a fully-qualified absolute path', 'REFERENCE_INVALID_CONFIG');
|
|
39
|
+
}
|
|
40
|
+
const lstatPath = options.lstatPath ?? (async (path) => lstat(path));
|
|
41
|
+
const accessPath = options.accessPath ?? (async (path, mode) => access(path, mode));
|
|
42
|
+
try {
|
|
43
|
+
const metadata = await lstatPath(value);
|
|
44
|
+
if (metadata.isSymbolicLink() || !metadata.isDirectory()) {
|
|
45
|
+
throw new ReferenceAnythingError('Cloud-drive download directory must name a real directory, not a symbolic link', 'REFERENCE_INVALID_CONFIG');
|
|
46
|
+
}
|
|
47
|
+
await accessPath(value, constants.W_OK | constants.X_OK);
|
|
48
|
+
}
|
|
49
|
+
catch (cause) {
|
|
50
|
+
if (cause instanceof ReferenceAnythingError)
|
|
51
|
+
throw cause;
|
|
52
|
+
throw new ReferenceAnythingError('Cloud-drive download directory does not exist or is not writable', 'REFERENCE_INVALID_CONFIG', { cause });
|
|
53
|
+
}
|
|
54
|
+
return value;
|
|
55
|
+
}
|
package/lib/errors.d.ts
CHANGED
|
@@ -16,8 +16,12 @@ export type ReferenceErrorCode =
|
|
|
16
16
|
| 'REFERENCE_NOT_FOUND'
|
|
17
17
|
/** A live browser read targeted a conversation owned by another account. */
|
|
18
18
|
| 'REFERENCE_ACCOUNT_MISMATCH'
|
|
19
|
+
/** The active provider account temporarily refused identity verification due to rate limiting. */
|
|
20
|
+
| 'PROVIDER_RATE_LIMIT'
|
|
19
21
|
/** The source failed while reading; its own error is the `cause`. */
|
|
20
22
|
| 'REFERENCE_READ_FAILED'
|
|
23
|
+
/** A transcript whose format must be read whole is larger than the scan budget. */
|
|
24
|
+
| 'REFERENCE_TRANSCRIPT_TOO_LARGE'
|
|
21
25
|
/** The caller cancelled before the read settled. */
|
|
22
26
|
| 'REFERENCE_CANCELLED'
|
|
23
27
|
/** A `dsh-ref:` URI was malformed, non-canonical, or not a reference at all. */
|
package/lib/host.d.ts
CHANGED
|
@@ -2,8 +2,52 @@ import type { Context } from '@deepseek-ai/cordis';
|
|
|
2
2
|
import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
3
3
|
import type { ChatProvider, SettingsRecord } from './store/spec.ts';
|
|
4
4
|
import type { SyncMode } from './sync/index.ts';
|
|
5
|
+
import type { Agent } from '@deepseek-ai/dsh-agent';
|
|
5
6
|
export declare class ReferenceAnythingRemote extends TypertRemoteService {
|
|
6
7
|
constructor(ctx: Context);
|
|
8
|
+
/**
|
|
9
|
+
* Discovery for the `@` menu's local-agent group.
|
|
10
|
+
*
|
|
11
|
+
* Resolved optionally rather than injected: `reference-anything-web` must
|
|
12
|
+
* still load in a profile where the local-agent plugin is switched off, and an
|
|
13
|
+
* absent service means an empty group, not a broken composer. Workspace
|
|
14
|
+
* scoping takes the session's own cwd, so a Web server serving projects from
|
|
15
|
+
* anywhere still scopes to the project the user is in.
|
|
16
|
+
*/
|
|
17
|
+
agentSearch(agent: Agent, input: {
|
|
18
|
+
query: string;
|
|
19
|
+
limit: number;
|
|
20
|
+
}, signal: AbortSignal): Promise<{
|
|
21
|
+
searchIncomplete?: boolean | undefined;
|
|
22
|
+
updatedAt?: number | undefined;
|
|
23
|
+
id: string;
|
|
24
|
+
kind: string;
|
|
25
|
+
label: string;
|
|
26
|
+
provider: string;
|
|
27
|
+
}[]>;
|
|
28
|
+
agentStats(signal: AbortSignal): Promise<{
|
|
29
|
+
agent: import("./sources/local-agent/types.ts").AgentKind;
|
|
30
|
+
conversations: number;
|
|
31
|
+
}[]>;
|
|
32
|
+
/**
|
|
33
|
+
* Discovery for the `@` menu's cloud-drive group.
|
|
34
|
+
*
|
|
35
|
+
* Optional for the same reason as `agentSearch` above. It takes no session:
|
|
36
|
+
* a drive is not scoped to a workspace, so there is nothing a cwd could
|
|
37
|
+
* narrow. `list` already refuses to name a download URL, so what comes back
|
|
38
|
+
* here is a label and a display path.
|
|
39
|
+
*/
|
|
40
|
+
driveSearch(input: {
|
|
41
|
+
query: string;
|
|
42
|
+
limit: number;
|
|
43
|
+
}, signal: AbortSignal): Promise<{
|
|
44
|
+
isDirectory?: boolean | undefined;
|
|
45
|
+
updatedAt?: number | undefined;
|
|
46
|
+
origin?: string | undefined;
|
|
47
|
+
id: string;
|
|
48
|
+
label: string;
|
|
49
|
+
provider: string;
|
|
50
|
+
}[]>;
|
|
7
51
|
search(input: {
|
|
8
52
|
query: string;
|
|
9
53
|
provider?: ChatProvider;
|
|
@@ -34,14 +78,19 @@ export declare class ReferenceAnythingRemote extends TypertRemoteService {
|
|
|
34
78
|
settingsUpdate(settings: SettingsRecord): Promise<{
|
|
35
79
|
opencliPath: string;
|
|
36
80
|
profile: string;
|
|
81
|
+
cloudDriveDownloadDirectory: string;
|
|
37
82
|
detailConcurrency: number;
|
|
38
83
|
autoSync: boolean;
|
|
39
84
|
syncOnStartup: boolean;
|
|
40
85
|
autoSyncMinutes: number;
|
|
41
86
|
historyMode: "metadata-only" | "offline-mirror";
|
|
87
|
+
syncHistoryDays: number | null;
|
|
42
88
|
enabledProviders: ("chatgpt" | "claude" | "gemini" | "deepseek" | "grok" | "kimi")[];
|
|
89
|
+
enabledAgents: ("kimi" | "claude-code" | "codex" | "cursor" | "qoder" | "reasonix" | "openclaw" | "grokbuild" | "hermes" | "gemini-cli" | "pi" | "opencode" | "mimocode" | "zcode")[];
|
|
43
90
|
maxReadTurns: number;
|
|
44
91
|
inputRenderMode: "pill" | "raw-text";
|
|
92
|
+
agentDirectories?: Partial<Record<"kimi" | "claude-code" | "codex" | "cursor" | "qoder" | "reasonix" | "openclaw" | "grokbuild" | "hermes" | "gemini-cli" | "pi" | "opencode" | "mimocode" | "zcode", string>> | undefined;
|
|
93
|
+
enabledDriveMounts?: string[] | undefined;
|
|
45
94
|
picker?: {
|
|
46
95
|
displayMode: "collapse" | "native-scroll";
|
|
47
96
|
commands: {
|
|
@@ -68,14 +117,27 @@ export declare class ReferenceAnythingRemote extends TypertRemoteService {
|
|
|
68
117
|
limit: number;
|
|
69
118
|
maxCandidates: number;
|
|
70
119
|
};
|
|
120
|
+
agents: {
|
|
121
|
+
enabled: boolean;
|
|
122
|
+
order: number;
|
|
123
|
+
limit: number;
|
|
124
|
+
maxCandidates: number;
|
|
125
|
+
};
|
|
71
126
|
conversations: {
|
|
72
127
|
enabled: boolean;
|
|
73
128
|
order: number;
|
|
74
129
|
limit: number;
|
|
75
130
|
maxCandidates: number;
|
|
76
131
|
};
|
|
132
|
+
drives: {
|
|
133
|
+
enabled: boolean;
|
|
134
|
+
order: number;
|
|
135
|
+
limit: number;
|
|
136
|
+
maxCandidates: number;
|
|
137
|
+
};
|
|
77
138
|
} | undefined;
|
|
78
139
|
}>;
|
|
140
|
+
openDownloadDirectory(signal: AbortSignal): Promise<boolean>;
|
|
79
141
|
browse(input: {
|
|
80
142
|
query: string;
|
|
81
143
|
provider?: ChatProvider;
|
|
@@ -92,10 +154,41 @@ export declare class ReferenceAnythingRemote extends TypertRemoteService {
|
|
|
92
154
|
clearProvider(input: {
|
|
93
155
|
provider: ChatProvider;
|
|
94
156
|
}, signal: AbortSignal): Promise<number>;
|
|
95
|
-
clearOlder(input: {
|
|
96
|
-
days: number;
|
|
97
|
-
}, signal: AbortSignal): Promise<number>;
|
|
98
157
|
clearRemoteMissing(signal: AbortSignal): Promise<number>;
|
|
99
158
|
clearOldAccounts(signal: AbortSignal): Promise<number>;
|
|
100
159
|
syncStates(): import("./store/store.ts").ProviderSyncState[];
|
|
160
|
+
openListStatus(signal: AbortSignal): Promise<import("./openlist/index.ts").OpenListStatus>;
|
|
161
|
+
openListInstall(signal: AbortSignal): Promise<import("./openlist/index.ts").OpenListStatus>;
|
|
162
|
+
openListUpgrade(input: {
|
|
163
|
+
rollback?: boolean;
|
|
164
|
+
}, signal: AbortSignal): Promise<import("./openlist/index.ts").OpenListStatus>;
|
|
165
|
+
openListConnectExternal(input: {
|
|
166
|
+
endpoint: string;
|
|
167
|
+
username?: string;
|
|
168
|
+
password?: string;
|
|
169
|
+
token?: string;
|
|
170
|
+
}, signal: AbortSignal): Promise<import("./openlist/index.ts").OpenListStatus>;
|
|
171
|
+
openListDisconnect(signal: AbortSignal): Promise<import("./openlist/index.ts").OpenListStatus>;
|
|
172
|
+
openListDrivers(signal: AbortSignal): Promise<import("./openlist/host.ts").OpenListDriver[]>;
|
|
173
|
+
openListMounts(signal: AbortSignal): Promise<import("./openlist/host.ts").OpenListMount[]>;
|
|
174
|
+
openListCreateMount(input: {
|
|
175
|
+
id?: string;
|
|
176
|
+
mountPath: string;
|
|
177
|
+
driver: string;
|
|
178
|
+
addition: Record<string, unknown>;
|
|
179
|
+
order?: number;
|
|
180
|
+
remark?: string;
|
|
181
|
+
}, signal: AbortSignal): Promise<import("./openlist/host.ts").OpenListMount>;
|
|
182
|
+
openListDisableMount(input: {
|
|
183
|
+
id: string;
|
|
184
|
+
disabled?: boolean;
|
|
185
|
+
}, signal: AbortSignal): Promise<boolean>;
|
|
186
|
+
openListRemoveMount(input: {
|
|
187
|
+
id: string;
|
|
188
|
+
}, signal: AbortSignal): Promise<boolean>;
|
|
189
|
+
openListReindex(input: {
|
|
190
|
+
id: string;
|
|
191
|
+
}, signal: AbortSignal): Promise<{
|
|
192
|
+
supported: true;
|
|
193
|
+
}>;
|
|
101
194
|
}
|
package/lib/host.js
CHANGED
|
@@ -1,6 +1,65 @@
|
|
|
1
1
|
import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { spawn } from 'node:child_process';
|
|
4
|
+
import { validateDownloadDirectory } from "./download-directory.js";
|
|
2
5
|
export class ReferenceAnythingRemote extends TypertRemoteService {
|
|
3
6
|
constructor(ctx) { super(ctx, 'referenceAnything'); }
|
|
7
|
+
/**
|
|
8
|
+
* Discovery for the `@` menu's local-agent group.
|
|
9
|
+
*
|
|
10
|
+
* Resolved optionally rather than injected: `reference-anything-web` must
|
|
11
|
+
* still load in a profile where the local-agent plugin is switched off, and an
|
|
12
|
+
* absent service means an empty group, not a broken composer. Workspace
|
|
13
|
+
* scoping takes the session's own cwd, so a Web server serving projects from
|
|
14
|
+
* anywhere still scopes to the project the user is in.
|
|
15
|
+
*/
|
|
16
|
+
async agentSearch(agent, input, signal) {
|
|
17
|
+
const agents = this.ctx.get('referenceLocalAgents');
|
|
18
|
+
if (agents === undefined)
|
|
19
|
+
return [];
|
|
20
|
+
// A session with no cwd of its own is rare and has no workspace to scope
|
|
21
|
+
// to; falling back to the process's directory is the same guess the
|
|
22
|
+
// `ReferenceSource.list` seam makes, rather than an empty group.
|
|
23
|
+
const rows = await agents.listForWorkspace(input.query, input.limit, agent.session.header.cwd ?? process.cwd(), signal);
|
|
24
|
+
return rows.map(row => ({
|
|
25
|
+
id: row.ref.id,
|
|
26
|
+
kind: row.ref.id.slice(0, row.ref.id.indexOf(':')),
|
|
27
|
+
label: row.label,
|
|
28
|
+
provider: row.provider ?? '',
|
|
29
|
+
...row.updatedAt === undefined ? {} : { updatedAt: row.updatedAt },
|
|
30
|
+
...row.searchIncomplete === true ? { searchIncomplete: true } : {},
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
async agentStats(signal) {
|
|
34
|
+
signal.throwIfAborted();
|
|
35
|
+
const agents = this.ctx.get('referenceLocalAgents');
|
|
36
|
+
if (agents === undefined)
|
|
37
|
+
return [];
|
|
38
|
+
agents.setAgentDirectories(this.ctx.referenceChatHistory.getSettings().agentDirectories ?? {});
|
|
39
|
+
return (await agents.stats(signal)).map(row => ({ agent: row.kind, conversations: row.conversations }));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Discovery for the `@` menu's cloud-drive group.
|
|
43
|
+
*
|
|
44
|
+
* Optional for the same reason as `agentSearch` above. It takes no session:
|
|
45
|
+
* a drive is not scoped to a workspace, so there is nothing a cwd could
|
|
46
|
+
* narrow. `list` already refuses to name a download URL, so what comes back
|
|
47
|
+
* here is a label and a display path.
|
|
48
|
+
*/
|
|
49
|
+
async driveSearch(input, signal) {
|
|
50
|
+
const drives = this.ctx.get('referenceCloudDrive');
|
|
51
|
+
if (drives === undefined)
|
|
52
|
+
return [];
|
|
53
|
+
const rows = await drives.pickerList(input.query, input.limit, signal);
|
|
54
|
+
return rows.map(row => ({
|
|
55
|
+
id: row.ref.id,
|
|
56
|
+
label: row.label,
|
|
57
|
+
provider: row.provider ?? '',
|
|
58
|
+
...row.origin === undefined ? {} : { origin: row.origin },
|
|
59
|
+
...row.updatedAt === undefined ? {} : { updatedAt: row.updatedAt },
|
|
60
|
+
...row.isDirectory === true ? { isDirectory: true } : {},
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
4
63
|
search(input, signal) {
|
|
5
64
|
signal.throwIfAborted();
|
|
6
65
|
return this.ctx.referenceChatHistory.search(input.query, input.provider, input.limit, signal);
|
|
@@ -22,7 +81,24 @@ export class ReferenceAnythingRemote extends TypertRemoteService {
|
|
|
22
81
|
syncStatus(input) { return this.ctx.referenceChatHistory.sync.status(input.jobId); }
|
|
23
82
|
syncCancel(input) { return this.ctx.referenceChatHistory.sync.cancel(input.jobId); }
|
|
24
83
|
settingsGet() { return this.ctx.referenceChatHistory.getSettings(); }
|
|
25
|
-
settingsUpdate(settings) {
|
|
84
|
+
async settingsUpdate(settings) {
|
|
85
|
+
const value = await this.ctx.referenceChatHistory.updateSettings(settings);
|
|
86
|
+
this.ctx.get('referenceLocalAgents')?.setAgentDirectories(value.agentDirectories ?? {});
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
async openDownloadDirectory(signal) {
|
|
90
|
+
signal.throwIfAborted();
|
|
91
|
+
const configured = this.ctx.referenceChatHistory.getSettings().cloudDriveDownloadDirectory;
|
|
92
|
+
const path = configured || tmpdir();
|
|
93
|
+
await validateDownloadDirectory(path);
|
|
94
|
+
const child = process.platform === 'win32'
|
|
95
|
+
? spawn('explorer.exe', [path], { detached: true, stdio: 'ignore' })
|
|
96
|
+
: process.platform === 'darwin'
|
|
97
|
+
? spawn('open', [path], { detached: true, stdio: 'ignore' })
|
|
98
|
+
: spawn('xdg-open', [path], { detached: true, stdio: 'ignore' });
|
|
99
|
+
child.unref();
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
26
102
|
browse(input, signal) {
|
|
27
103
|
signal.throwIfAborted();
|
|
28
104
|
return this.ctx.referenceChatHistory.browse(input.query, input.provider, input.limit, input.offset);
|
|
@@ -36,10 +112,6 @@ export class ReferenceAnythingRemote extends TypertRemoteService {
|
|
|
36
112
|
signal.throwIfAborted();
|
|
37
113
|
return this.ctx.referenceChatHistory.removeProvider(input.provider);
|
|
38
114
|
}
|
|
39
|
-
clearOlder(input, signal) {
|
|
40
|
-
signal.throwIfAborted();
|
|
41
|
-
return this.ctx.referenceChatHistory.removeOlderThan(input.days);
|
|
42
|
-
}
|
|
43
115
|
clearRemoteMissing(signal) {
|
|
44
116
|
signal.throwIfAborted();
|
|
45
117
|
return this.ctx.referenceChatHistory.removeRemoteMissing();
|
|
@@ -49,4 +121,15 @@ export class ReferenceAnythingRemote extends TypertRemoteService {
|
|
|
49
121
|
return this.ctx.referenceChatHistory.removeOldAccounts();
|
|
50
122
|
}
|
|
51
123
|
syncStates() { return this.ctx.referenceChatHistory.syncStates(); }
|
|
124
|
+
openListStatus(signal) { return this.ctx.openListManager.status(signal); }
|
|
125
|
+
openListInstall(signal) { return this.ctx.openListManager.install(signal); }
|
|
126
|
+
openListUpgrade(input, signal) { return this.ctx.openListManager.upgrade(input, signal); }
|
|
127
|
+
openListConnectExternal(input, signal) { return this.ctx.openListManager.connectExternal(input, signal); }
|
|
128
|
+
openListDisconnect(signal) { return this.ctx.openListManager.disconnect(signal); }
|
|
129
|
+
openListDrivers(signal) { return this.ctx.openListManager.drivers(signal); }
|
|
130
|
+
openListMounts(signal) { return this.ctx.openListManager.mounts(signal); }
|
|
131
|
+
openListCreateMount(input, signal) { return this.ctx.openListManager.createMount(input, signal); }
|
|
132
|
+
async openListDisableMount(input, signal) { await this.ctx.openListManager.disableMount(input.id, input.disabled ?? true, signal); return true; }
|
|
133
|
+
async openListRemoveMount(input, signal) { await this.ctx.openListManager.removeMount(input.id, signal); return true; }
|
|
134
|
+
openListReindex(input, signal) { return this.ctx.openListManager.reindexMount(input.id, signal); }
|
|
52
135
|
}
|