dsh-reference-anything 0.3.0 → 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 +339 -286
- package/cordis.patch.yml +89 -18
- package/lib/client.js +13538 -591
- package/lib/contract.d.ts +155 -16
- package/lib/contract.js +68 -7
- 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 -8
- package/lib/host.js +88 -19
- 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 -4
- 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 -2
- 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 -9
- package/lib/wire.js +30 -4
- 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 +182 -167
- package/lib/profile-mode.d.ts +0 -30
- package/lib/profile-mode.js +0 -90
package/lib/update.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
export declare const PACKAGE_NAME = "dsh-reference-anything";
|
|
2
2
|
export declare const NPM_LATEST_URL = "https://registry.npmjs.org/dsh-reference-anything/latest";
|
|
3
|
+
export declare const GITHUB_RELEASE_URL = "https://api.github.com/repos/Chael-Chael/dsh-reference-anything/releases/tags";
|
|
3
4
|
export interface PackageUpdateStatus {
|
|
4
5
|
currentVersion: string;
|
|
5
6
|
latestVersion: string;
|
|
6
7
|
updateAvailable: boolean;
|
|
7
8
|
checkedAt: number;
|
|
9
|
+
releaseNotes?: string;
|
|
10
|
+
releaseUrl?: string;
|
|
8
11
|
error?: string;
|
|
9
12
|
}
|
|
10
13
|
export interface PackageUpdateResult {
|
|
@@ -15,6 +18,7 @@ interface UpdateManagerOptions {
|
|
|
15
18
|
packageRoot?: string;
|
|
16
19
|
dshHome?: string;
|
|
17
20
|
fetchLatest?: (signal?: AbortSignal) => Promise<string>;
|
|
21
|
+
fetchReleaseNotes?: (version: string, signal?: AbortSignal) => Promise<Pick<PackageUpdateStatus, 'releaseNotes' | 'releaseUrl'>>;
|
|
18
22
|
install?: (profileDir: string, version: string, signal?: AbortSignal) => Promise<void>;
|
|
19
23
|
afterInstall?: (profileDir: string, version: string, signal?: AbortSignal) => Promise<void>;
|
|
20
24
|
}
|
|
@@ -23,6 +27,7 @@ export declare class PackageUpdateManager {
|
|
|
23
27
|
private readonly packageRoot;
|
|
24
28
|
private readonly dshHome?;
|
|
25
29
|
private readonly fetchLatest;
|
|
30
|
+
private readonly fetchReleaseNotes;
|
|
26
31
|
private readonly install;
|
|
27
32
|
private readonly afterInstall?;
|
|
28
33
|
private cached?;
|
|
@@ -37,6 +42,7 @@ export declare class PackageUpdateManager {
|
|
|
37
42
|
private runCheck;
|
|
38
43
|
}
|
|
39
44
|
export declare function fetchLatestVersion(signal?: AbortSignal): Promise<string>;
|
|
45
|
+
export declare function fetchGitHubReleaseNotes(version: string, signal?: AbortSignal): Promise<Pick<PackageUpdateStatus, 'releaseNotes' | 'releaseUrl'>>;
|
|
40
46
|
export declare function readPackageVersion(packageRoot?: string): Promise<string>;
|
|
41
47
|
/** Find the profile that owns this exact installed package, including pnpm links. */
|
|
42
48
|
export declare function findOwningProfileDir(packageRoot?: string, configuredDshHome?: string): Promise<string>;
|
package/lib/update.js
CHANGED
|
@@ -7,6 +7,7 @@ import { promisify } from 'node:util';
|
|
|
7
7
|
const execFile = promisify(nodeExecFile);
|
|
8
8
|
export const PACKAGE_NAME = 'dsh-reference-anything';
|
|
9
9
|
export const NPM_LATEST_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
10
|
+
export const GITHUB_RELEASE_URL = 'https://api.github.com/repos/Chael-Chael/dsh-reference-anything/releases/tags';
|
|
10
11
|
const PACKAGE_ROOT = resolve(fileURLToPath(new URL('../', import.meta.url)));
|
|
11
12
|
const UPDATE_TIMEOUT_MS = 5 * 60_000;
|
|
12
13
|
const CHECK_TIMEOUT_MS = 10_000;
|
|
@@ -15,6 +16,7 @@ export class PackageUpdateManager {
|
|
|
15
16
|
packageRoot;
|
|
16
17
|
dshHome;
|
|
17
18
|
fetchLatest;
|
|
19
|
+
fetchReleaseNotes;
|
|
18
20
|
install;
|
|
19
21
|
afterInstall;
|
|
20
22
|
cached;
|
|
@@ -23,6 +25,7 @@ export class PackageUpdateManager {
|
|
|
23
25
|
this.packageRoot = resolve(options.packageRoot ?? PACKAGE_ROOT);
|
|
24
26
|
this.dshHome = options.dshHome;
|
|
25
27
|
this.fetchLatest = options.fetchLatest ?? fetchLatestVersion;
|
|
28
|
+
this.fetchReleaseNotes = options.fetchReleaseNotes ?? fetchGitHubReleaseNotes;
|
|
26
29
|
this.install = options.install ?? installPackageVersion;
|
|
27
30
|
this.afterInstall = options.afterInstall;
|
|
28
31
|
}
|
|
@@ -60,6 +63,8 @@ export class PackageUpdateManager {
|
|
|
60
63
|
latestVersion: status.latestVersion,
|
|
61
64
|
updateAvailable: false,
|
|
62
65
|
checkedAt: Date.now(),
|
|
66
|
+
releaseNotes: status.releaseNotes,
|
|
67
|
+
releaseUrl: status.releaseUrl,
|
|
63
68
|
};
|
|
64
69
|
return { version: status.latestVersion, restartRequired: true };
|
|
65
70
|
}
|
|
@@ -69,11 +74,18 @@ export class PackageUpdateManager {
|
|
|
69
74
|
try {
|
|
70
75
|
currentVersion = await readPackageVersion(this.packageRoot);
|
|
71
76
|
const latestVersion = await this.fetchLatest(signal);
|
|
77
|
+
const updateAvailable = compareVersions(latestVersion, currentVersion) > 0;
|
|
78
|
+
let release = {};
|
|
79
|
+
try {
|
|
80
|
+
release = await this.fetchReleaseNotes(latestVersion, signal);
|
|
81
|
+
}
|
|
82
|
+
catch { /* Release notes are advisory. */ }
|
|
72
83
|
const status = {
|
|
73
84
|
currentVersion,
|
|
74
85
|
latestVersion,
|
|
75
|
-
updateAvailable
|
|
86
|
+
updateAvailable,
|
|
76
87
|
checkedAt,
|
|
88
|
+
...release,
|
|
77
89
|
};
|
|
78
90
|
this.cached = status;
|
|
79
91
|
return status;
|
|
@@ -107,6 +119,22 @@ export async function fetchLatestVersion(signal) {
|
|
|
107
119
|
throw new Error('npm registry returned an invalid version');
|
|
108
120
|
return body.version;
|
|
109
121
|
}
|
|
122
|
+
export async function fetchGitHubReleaseNotes(version, signal) {
|
|
123
|
+
if (!isVersion(version))
|
|
124
|
+
throw new Error('refusing to request an invalid release version');
|
|
125
|
+
const timeout = AbortSignal.timeout(CHECK_TIMEOUT_MS);
|
|
126
|
+
const response = await fetch(`${GITHUB_RELEASE_URL}/v${version}`, {
|
|
127
|
+
headers: { accept: 'application/vnd.github+json', 'user-agent': PACKAGE_NAME, 'x-github-api-version': '2022-11-28' },
|
|
128
|
+
signal: signal ? AbortSignal.any([signal, timeout]) : timeout,
|
|
129
|
+
});
|
|
130
|
+
if (!response.ok)
|
|
131
|
+
throw new Error(`GitHub returned HTTP ${String(response.status)}`);
|
|
132
|
+
const body = await response.json();
|
|
133
|
+
return {
|
|
134
|
+
releaseNotes: typeof body.body === 'string' ? body.body.trim().slice(0, 12_000) || undefined : undefined,
|
|
135
|
+
releaseUrl: typeof body.html_url === 'string' ? body.html_url : undefined,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
110
138
|
export async function readPackageVersion(packageRoot = PACKAGE_ROOT) {
|
|
111
139
|
const manifest = await readJson(join(packageRoot, 'package.json'));
|
|
112
140
|
if (typeof manifest.version !== 'string' || !isVersion(manifest.version))
|
package/lib/web.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { ReferenceAnythingRemote } from "./host.js";
|
|
2
2
|
import { TYPERT_MANIFEST } from "./typert.js";
|
|
3
3
|
export const name = 'reference-anything-web';
|
|
4
|
-
|
|
4
|
+
// `referenceCloudDrive` is consumed lazily by ReferenceAnythingRemote when the
|
|
5
|
+
// composer asks for @drive candidates. Declare it here so Cordis exposes the
|
|
6
|
+
// sibling service in this plugin scope instead of making driveSearch silently
|
|
7
|
+
// look like an unconfigured installation.
|
|
8
|
+
export const inject = ['typert', 'referenceChatHistory', 'openListManager', 'referenceCloudDrive'];
|
|
5
9
|
export function apply(ctx) {
|
|
6
10
|
new ReferenceAnythingRemote(ctx);
|
|
7
11
|
ctx.effect(() => {
|
package/lib/wire.d.ts
CHANGED
|
@@ -10,12 +10,33 @@ export declare const providerSchema: z.ZodEnum<{
|
|
|
10
10
|
}>;
|
|
11
11
|
export type ChatProvider = z.infer<typeof providerSchema>;
|
|
12
12
|
export declare const ALL_PROVIDERS: readonly ChatProvider[];
|
|
13
|
+
export declare const localAgentSchema: z.ZodEnum<{
|
|
14
|
+
kimi: "kimi";
|
|
15
|
+
"claude-code": "claude-code";
|
|
16
|
+
codex: "codex";
|
|
17
|
+
cursor: "cursor";
|
|
18
|
+
qoder: "qoder";
|
|
19
|
+
reasonix: "reasonix";
|
|
20
|
+
openclaw: "openclaw";
|
|
21
|
+
grokbuild: "grokbuild";
|
|
22
|
+
hermes: "hermes";
|
|
23
|
+
"gemini-cli": "gemini-cli";
|
|
24
|
+
pi: "pi";
|
|
25
|
+
opencode: "opencode";
|
|
26
|
+
mimocode: "mimocode";
|
|
27
|
+
zcode: "zcode";
|
|
28
|
+
}>;
|
|
29
|
+
export type LocalAgent = z.infer<typeof localAgentSchema>;
|
|
30
|
+
export declare const ALL_LOCAL_AGENTS: readonly LocalAgent[];
|
|
31
|
+
export declare const LOCAL_AGENT_LABEL: Readonly<Record<LocalAgent, string>>;
|
|
13
32
|
export declare const pickerSourceSchema: z.ZodEnum<{
|
|
14
33
|
commands: "commands";
|
|
15
34
|
skills: "skills";
|
|
16
35
|
files: "files";
|
|
17
36
|
sessions: "sessions";
|
|
37
|
+
agents: "agents";
|
|
18
38
|
conversations: "conversations";
|
|
39
|
+
drives: "drives";
|
|
19
40
|
}>;
|
|
20
41
|
export type PickerSource = z.infer<typeof pickerSourceSchema>;
|
|
21
42
|
declare const pickerSourceSettingsSchema: z.ZodObject<{
|
|
@@ -54,12 +75,24 @@ export declare const pickerSettingsSchema: z.ZodObject<{
|
|
|
54
75
|
limit: z.ZodNumber;
|
|
55
76
|
maxCandidates: z.ZodDefault<z.ZodNumber>;
|
|
56
77
|
}, z.core.$strip>;
|
|
78
|
+
agents: z.ZodDefault<z.ZodObject<{
|
|
79
|
+
enabled: z.ZodBoolean;
|
|
80
|
+
order: z.ZodNumber;
|
|
81
|
+
limit: z.ZodNumber;
|
|
82
|
+
maxCandidates: z.ZodDefault<z.ZodNumber>;
|
|
83
|
+
}, z.core.$strip>>;
|
|
57
84
|
conversations: z.ZodObject<{
|
|
58
85
|
enabled: z.ZodBoolean;
|
|
59
86
|
order: z.ZodNumber;
|
|
60
87
|
limit: z.ZodNumber;
|
|
61
88
|
maxCandidates: z.ZodDefault<z.ZodNumber>;
|
|
62
89
|
}, z.core.$strip>;
|
|
90
|
+
drives: z.ZodDefault<z.ZodObject<{
|
|
91
|
+
enabled: z.ZodBoolean;
|
|
92
|
+
order: z.ZodNumber;
|
|
93
|
+
limit: z.ZodNumber;
|
|
94
|
+
maxCandidates: z.ZodDefault<z.ZodNumber>;
|
|
95
|
+
}, z.core.$strip>>;
|
|
63
96
|
}, z.core.$strip>;
|
|
64
97
|
export type PickerSettings = z.infer<typeof pickerSettingsSchema>;
|
|
65
98
|
export type PickerDisplayMode = PickerSettings['displayMode'];
|
|
@@ -68,11 +101,6 @@ export declare const inputRenderModeSchema: z.ZodEnum<{
|
|
|
68
101
|
"raw-text": "raw-text";
|
|
69
102
|
}>;
|
|
70
103
|
export type InputRenderMode = z.infer<typeof inputRenderModeSchema>;
|
|
71
|
-
export declare const referenceUiModeSchema: z.ZodEnum<{
|
|
72
|
-
plugin: "plugin";
|
|
73
|
-
official: "official";
|
|
74
|
-
}>;
|
|
75
|
-
export type ReferenceUiMode = z.infer<typeof referenceUiModeSchema>;
|
|
76
104
|
/** Defaults used before the user saves the General section. */
|
|
77
105
|
export declare function defaultPickerSettings(): PickerSettings;
|
|
78
106
|
/** Picker settings have a fixed schema, so explicit comparison is cheap and stable. */
|
|
@@ -80,6 +108,7 @@ export declare function samePickerSettings(left: PickerSettings, right: PickerSe
|
|
|
80
108
|
export declare const settingsRecordSchema: z.ZodObject<{
|
|
81
109
|
opencliPath: z.ZodString;
|
|
82
110
|
profile: z.ZodString;
|
|
111
|
+
cloudDriveDownloadDirectory: z.ZodDefault<z.ZodString>;
|
|
83
112
|
detailConcurrency: z.ZodNumber;
|
|
84
113
|
autoSync: z.ZodDefault<z.ZodBoolean>;
|
|
85
114
|
syncOnStartup: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -88,6 +117,7 @@ export declare const settingsRecordSchema: z.ZodObject<{
|
|
|
88
117
|
"metadata-only": "metadata-only";
|
|
89
118
|
"offline-mirror": "offline-mirror";
|
|
90
119
|
}>>;
|
|
120
|
+
syncHistoryDays: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
|
|
91
121
|
enabledProviders: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
92
122
|
chatgpt: "chatgpt";
|
|
93
123
|
claude: "claude";
|
|
@@ -96,15 +126,44 @@ export declare const settingsRecordSchema: z.ZodObject<{
|
|
|
96
126
|
grok: "grok";
|
|
97
127
|
kimi: "kimi";
|
|
98
128
|
}>>>;
|
|
129
|
+
enabledAgents: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
130
|
+
kimi: "kimi";
|
|
131
|
+
"claude-code": "claude-code";
|
|
132
|
+
codex: "codex";
|
|
133
|
+
cursor: "cursor";
|
|
134
|
+
qoder: "qoder";
|
|
135
|
+
reasonix: "reasonix";
|
|
136
|
+
openclaw: "openclaw";
|
|
137
|
+
grokbuild: "grokbuild";
|
|
138
|
+
hermes: "hermes";
|
|
139
|
+
"gemini-cli": "gemini-cli";
|
|
140
|
+
pi: "pi";
|
|
141
|
+
opencode: "opencode";
|
|
142
|
+
mimocode: "mimocode";
|
|
143
|
+
zcode: "zcode";
|
|
144
|
+
}>>>;
|
|
145
|
+
agentDirectories: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
146
|
+
kimi: "kimi";
|
|
147
|
+
"claude-code": "claude-code";
|
|
148
|
+
codex: "codex";
|
|
149
|
+
cursor: "cursor";
|
|
150
|
+
qoder: "qoder";
|
|
151
|
+
reasonix: "reasonix";
|
|
152
|
+
openclaw: "openclaw";
|
|
153
|
+
grokbuild: "grokbuild";
|
|
154
|
+
hermes: "hermes";
|
|
155
|
+
"gemini-cli": "gemini-cli";
|
|
156
|
+
pi: "pi";
|
|
157
|
+
opencode: "opencode";
|
|
158
|
+
mimocode: "mimocode";
|
|
159
|
+
zcode: "zcode";
|
|
160
|
+
}> & z.core.$partial, z.ZodString>>;
|
|
161
|
+
enabledDriveMounts: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
99
162
|
maxReadTurns: z.ZodDefault<z.ZodNumber>;
|
|
100
163
|
inputRenderMode: z.ZodDefault<z.ZodEnum<{
|
|
101
164
|
pill: "pill";
|
|
102
165
|
"raw-text": "raw-text";
|
|
103
166
|
}>>;
|
|
104
|
-
referenceUiMode: z.ZodOptional<z.ZodEnum<{
|
|
105
|
-
plugin: "plugin";
|
|
106
|
-
official: "official";
|
|
107
|
-
}>>;
|
|
108
167
|
picker: z.ZodOptional<z.ZodObject<{
|
|
109
168
|
displayMode: z.ZodDefault<z.ZodEnum<{
|
|
110
169
|
collapse: "collapse";
|
|
@@ -134,12 +193,24 @@ export declare const settingsRecordSchema: z.ZodObject<{
|
|
|
134
193
|
limit: z.ZodNumber;
|
|
135
194
|
maxCandidates: z.ZodDefault<z.ZodNumber>;
|
|
136
195
|
}, z.core.$strip>;
|
|
196
|
+
agents: z.ZodDefault<z.ZodObject<{
|
|
197
|
+
enabled: z.ZodBoolean;
|
|
198
|
+
order: z.ZodNumber;
|
|
199
|
+
limit: z.ZodNumber;
|
|
200
|
+
maxCandidates: z.ZodDefault<z.ZodNumber>;
|
|
201
|
+
}, z.core.$strip>>;
|
|
137
202
|
conversations: z.ZodObject<{
|
|
138
203
|
enabled: z.ZodBoolean;
|
|
139
204
|
order: z.ZodNumber;
|
|
140
205
|
limit: z.ZodNumber;
|
|
141
206
|
maxCandidates: z.ZodDefault<z.ZodNumber>;
|
|
142
207
|
}, z.core.$strip>;
|
|
208
|
+
drives: z.ZodDefault<z.ZodObject<{
|
|
209
|
+
enabled: z.ZodBoolean;
|
|
210
|
+
order: z.ZodNumber;
|
|
211
|
+
limit: z.ZodNumber;
|
|
212
|
+
maxCandidates: z.ZodDefault<z.ZodNumber>;
|
|
213
|
+
}, z.core.$strip>>;
|
|
143
214
|
}, z.core.$strip>>;
|
|
144
215
|
}, z.core.$strip>;
|
|
145
216
|
export type SettingsRecord = z.infer<typeof settingsRecordSchema>;
|
package/lib/wire.js
CHANGED
|
@@ -2,7 +2,14 @@
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
export const providerSchema = z.enum(['chatgpt', 'claude', 'gemini', 'deepseek', 'grok', 'kimi']);
|
|
4
4
|
export const ALL_PROVIDERS = providerSchema.options;
|
|
5
|
-
export const
|
|
5
|
+
export const localAgentSchema = z.enum(['claude-code', 'codex', 'cursor', 'qoder', 'reasonix', 'openclaw', 'kimi', 'grokbuild', 'hermes', 'gemini-cli', 'pi', 'opencode', 'mimocode', 'zcode']);
|
|
6
|
+
export const ALL_LOCAL_AGENTS = localAgentSchema.options;
|
|
7
|
+
export const LOCAL_AGENT_LABEL = {
|
|
8
|
+
'claude-code': 'Claude Code', codex: 'Codex', cursor: 'Cursor', qoder: 'Qoder', reasonix: 'Reasonix',
|
|
9
|
+
openclaw: 'OpenClaw', kimi: 'Kimi', grokbuild: 'Grok Build', hermes: 'Hermes', 'gemini-cli': 'Gemini CLI',
|
|
10
|
+
pi: 'Pi', opencode: 'opencode', mimocode: 'mimocode', zcode: 'zcode',
|
|
11
|
+
};
|
|
12
|
+
export const pickerSourceSchema = z.enum(['commands', 'skills', 'files', 'sessions', 'agents', 'conversations', 'drives']);
|
|
6
13
|
const pickerSourceSettingsSchema = z.object({
|
|
7
14
|
enabled: z.boolean(),
|
|
8
15
|
order: z.number().int().min(0).max(100),
|
|
@@ -15,10 +22,17 @@ export const pickerSettingsSchema = z.object({
|
|
|
15
22
|
skills: pickerSourceSettingsSchema,
|
|
16
23
|
files: pickerSourceSettingsSchema,
|
|
17
24
|
sessions: pickerSourceSettingsSchema,
|
|
25
|
+
// Defaulted, unlike its neighbours, because this key arrived after settings
|
|
26
|
+
// were already on disk. `settingsRecordSchema` is the durable read boundary:
|
|
27
|
+
// a saved record that has `picker` but predates this key would fail the whole
|
|
28
|
+
// parse without it, and the medium — every setting in it — would be rejected.
|
|
29
|
+
// Any key added here from now on needs the same treatment.
|
|
30
|
+
agents: pickerSourceSettingsSchema.default({ enabled: true, order: 25, limit: 6, maxCandidates: 50 }),
|
|
18
31
|
conversations: pickerSourceSettingsSchema,
|
|
32
|
+
// Defaulted for the same reason as `agents` above: it arrived later still.
|
|
33
|
+
drives: pickerSourceSettingsSchema.default({ enabled: true, order: 35, limit: 6, maxCandidates: 50 }),
|
|
19
34
|
});
|
|
20
35
|
export const inputRenderModeSchema = z.enum(['pill', 'raw-text']);
|
|
21
|
-
export const referenceUiModeSchema = z.enum(['plugin', 'official']);
|
|
22
36
|
/** Defaults used before the user saves the General section. */
|
|
23
37
|
export function defaultPickerSettings() {
|
|
24
38
|
return {
|
|
@@ -27,7 +41,9 @@ export function defaultPickerSettings() {
|
|
|
27
41
|
skills: { enabled: true, order: 5, limit: 6, maxCandidates: 50 },
|
|
28
42
|
files: { enabled: true, order: 10, limit: 6, maxCandidates: 50 },
|
|
29
43
|
sessions: { enabled: true, order: 20, limit: 6, maxCandidates: 50 },
|
|
44
|
+
agents: { enabled: true, order: 25, limit: 6, maxCandidates: 50 },
|
|
30
45
|
conversations: { enabled: true, order: 30, limit: 6, maxCandidates: 50 },
|
|
46
|
+
drives: { enabled: true, order: 35, limit: 6, maxCandidates: 50 },
|
|
31
47
|
};
|
|
32
48
|
}
|
|
33
49
|
/** Picker settings have a fixed schema, so explicit comparison is cheap and stable. */
|
|
@@ -42,16 +58,26 @@ export function samePickerSettings(left, right) {
|
|
|
42
58
|
export const settingsRecordSchema = z.object({
|
|
43
59
|
opencliPath: z.string(),
|
|
44
60
|
profile: z.string(),
|
|
61
|
+
/** Empty keeps the original system-temporary-directory behavior. */
|
|
62
|
+
cloudDriveDownloadDirectory: z.string().max(4096).default(''),
|
|
45
63
|
detailConcurrency: z.number().int().min(1).max(8),
|
|
46
64
|
autoSync: z.boolean().default(false),
|
|
47
65
|
syncOnStartup: z.boolean().default(false),
|
|
48
66
|
autoSyncMinutes: z.number().int().min(15).max(1440).default(60),
|
|
49
67
|
historyMode: z.enum(['metadata-only', 'offline-mirror']).default('metadata-only'),
|
|
68
|
+
/** Null keeps all web-chat history; old settings default to that upgrade-safe behavior. */
|
|
69
|
+
syncHistoryDays: z.number().int().min(1).max(36500).nullable().default(null),
|
|
50
70
|
enabledProviders: z.array(providerSchema).default([...ALL_PROVIDERS]),
|
|
71
|
+
enabledAgents: z.array(localAgentSchema).default([...ALL_LOCAL_AGENTS]),
|
|
72
|
+
/** One optional additional transcript root per local Agent. */
|
|
73
|
+
agentDirectories: z.partialRecord(localAgentSchema, z.string().max(4096)).optional(),
|
|
74
|
+
/**
|
|
75
|
+
* OpenList mount paths shown by the drive picker. Undefined preserves the
|
|
76
|
+
* legacy behaviour (all enabled mounts); an explicit empty array means none.
|
|
77
|
+
*/
|
|
78
|
+
enabledDriveMounts: z.array(z.string().startsWith('/')).optional(),
|
|
51
79
|
maxReadTurns: z.number().int().min(1).max(100).default(10),
|
|
52
80
|
inputRenderMode: inputRenderModeSchema.default('pill'),
|
|
53
|
-
// Optional keeps settings written by earlier plugin versions readable.
|
|
54
|
-
referenceUiMode: referenceUiModeSchema.optional(),
|
|
55
81
|
// Optional keeps existing on-disk settings forward-compatible. The client
|
|
56
82
|
// uses defaultPickerSettings() until the user saves the General section.
|
|
57
83
|
picker: pickerSettingsSchema.optional(),
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { domFallbackScript, registerProvider, sinceGuardSource } from './common.js'
|
|
2
|
-
// OpenCLI discovery marker: registerProvider below performs the cli() calls.
|
|
3
|
-
|
|
4
|
-
export const timestampSource = String.raw`value => {
|
|
5
|
-
if (value === undefined || value === null || value === '') return ''
|
|
6
|
-
if (typeof value === 'string' && Number.isNaN(Number(value))) {
|
|
7
|
-
const parsed = Date.parse(value)
|
|
8
|
-
return Number.isNaN(parsed) ? '' : new Date(parsed).toISOString()
|
|
9
|
-
}
|
|
10
|
-
const numeric = Number(value)
|
|
11
|
-
if (!Number.isFinite(numeric) || numeric <= 0) return ''
|
|
12
|
-
const milliseconds = numeric < 1e11 ? numeric * 1000
|
|
13
|
-
: numeric < 1e14 ? numeric : numeric < 1e17 ? numeric / 1000 : numeric / 1e6
|
|
14
|
-
const date = new Date(milliseconds)
|
|
15
|
-
return Number.isNaN(date.getTime()) ? '' : date.toISOString()
|
|
16
|
-
}`
|
|
17
|
-
|
|
18
|
-
export const historyScript = String.raw`async function (args) {
|
|
19
|
-
const stopEarly = (${sinceGuardSource})(args && args.since)
|
|
20
|
-
const toIso = (${timestampSource})
|
|
1
|
+
import { domFallbackScript, registerProvider, sinceGuardSource } from './common.js'
|
|
2
|
+
// OpenCLI discovery marker: registerProvider below performs the cli() calls.
|
|
3
|
+
|
|
4
|
+
export const timestampSource = String.raw`value => {
|
|
5
|
+
if (value === undefined || value === null || value === '') return ''
|
|
6
|
+
if (typeof value === 'string' && Number.isNaN(Number(value))) {
|
|
7
|
+
const parsed = Date.parse(value)
|
|
8
|
+
return Number.isNaN(parsed) ? '' : new Date(parsed).toISOString()
|
|
9
|
+
}
|
|
10
|
+
const numeric = Number(value)
|
|
11
|
+
if (!Number.isFinite(numeric) || numeric <= 0) return ''
|
|
12
|
+
const milliseconds = numeric < 1e11 ? numeric * 1000
|
|
13
|
+
: numeric < 1e14 ? numeric : numeric < 1e17 ? numeric / 1000 : numeric / 1e6
|
|
14
|
+
const date = new Date(milliseconds)
|
|
15
|
+
return Number.isNaN(date.getTime()) ? '' : date.toISOString()
|
|
16
|
+
}`
|
|
17
|
+
|
|
18
|
+
export const historyScript = String.raw`async function (args) {
|
|
19
|
+
const stopEarly = (${sinceGuardSource})(args && args.since)
|
|
20
|
+
const toIso = (${timestampSource})
|
|
21
21
|
const fallback = () => Array.from(document.querySelectorAll('a[href*="/c/"]')).map((a, i) => {
|
|
22
22
|
const match = a.href.match(/\/c\/([^/?#]+)/)
|
|
23
23
|
return match ? { provider: 'chatgpt', accountScope: '', id: match[1], title: (a.innerText || a.textContent || 'Untitled').trim(), url: a.href, createdAt: '', updatedAt: '', messageCount: '', cursor: '', partial: true } : null
|
|
@@ -40,8 +40,8 @@ export const historyScript = String.raw`async function (args) {
|
|
|
40
40
|
for (const item of items) rows.push({
|
|
41
41
|
provider: 'chatgpt', accountScope: '', id: String(item.id), title: item.title || 'Untitled Conversation',
|
|
42
42
|
url: location.origin + '/c/' + item.id,
|
|
43
|
-
createdAt: toIso(item.create_time),
|
|
44
|
-
updatedAt: toIso(item.update_time),
|
|
43
|
+
createdAt: toIso(item.create_time),
|
|
44
|
+
updatedAt: toIso(item.update_time),
|
|
45
45
|
messageCount: item.message_count || item.messageCount || '', cursor: '', partial: false,
|
|
46
46
|
})
|
|
47
47
|
if (items.length < 100) return JSON.stringify({ ok: true, rows })
|
|
@@ -110,16 +110,19 @@ const detailScript = String.raw`async function (args) {
|
|
|
110
110
|
}
|
|
111
111
|
}`
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
site: 'dsh-chatgpt', provider: 'ChatGPT', domain: 'chatgpt.com', home: 'https://chatgpt.com/',
|
|
115
|
-
conversationUrl: id => `https://chatgpt.com/c/${encodeURIComponent(id)}`,
|
|
116
|
-
whoamiScript: String.raw`async function () {
|
|
113
|
+
export const whoamiScript = String.raw`async function () {
|
|
117
114
|
const response = await fetch('/api/auth/session', { credentials: 'include' })
|
|
118
115
|
if (response.status === 401 || response.status === 403) return JSON.stringify({ ok: false, code: 'AUTH' })
|
|
116
|
+
if (response.status === 429) return JSON.stringify({ ok: false, code: 'RATE_LIMIT' })
|
|
119
117
|
if (!response.ok) return JSON.stringify({ ok: false, message: 'session HTTP ' + response.status })
|
|
120
118
|
const payload = await response.json(); const user = payload.user || payload.account || {}
|
|
121
119
|
const identity = String(user.id || user.account_id || user.email || '')
|
|
122
120
|
return JSON.stringify({ ok: Boolean(identity), identity, code: identity ? undefined : 'AUTH' })
|
|
123
|
-
}
|
|
121
|
+
}`
|
|
122
|
+
|
|
123
|
+
registerProvider({
|
|
124
|
+
site: 'dsh-chatgpt', provider: 'ChatGPT', domain: 'chatgpt.com', home: 'https://chatgpt.com/',
|
|
125
|
+
conversationUrl: id => `https://chatgpt.com/c/${encodeURIComponent(id)}`,
|
|
126
|
+
whoamiScript,
|
|
124
127
|
historyScript, detailScript, fallbackScript: domFallbackScript,
|
|
125
128
|
})
|
package/opencli-plugin/claude.js
CHANGED
|
@@ -119,16 +119,20 @@ const detailScript = String.raw`async function (args) {
|
|
|
119
119
|
}
|
|
120
120
|
}`
|
|
121
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
|
+
|
|
122
133
|
registerProvider({
|
|
123
134
|
site: 'dsh-claude', provider: 'Claude', domain: 'claude.ai', home: 'https://claude.ai/',
|
|
124
135
|
conversationUrl: id => `https://claude.ai/chat/${encodeURIComponent(id)}`,
|
|
125
|
-
whoamiScript
|
|
126
|
-
const response = await fetch('/api/organizations', { credentials: 'include' })
|
|
127
|
-
if (response.status === 401 || response.status === 403) return JSON.stringify({ ok: false, code: 'AUTH' })
|
|
128
|
-
if (!response.ok) return JSON.stringify({ ok: false, message: 'organizations HTTP ' + response.status })
|
|
129
|
-
const payload = await response.json(); const values = Array.isArray(payload) ? payload : payload.organizations || []
|
|
130
|
-
const item = values.find(value => value && (value.uuid || value.id)); const identity = String(item && (item.uuid || item.id) || '')
|
|
131
|
-
return JSON.stringify({ ok: Boolean(identity), identity, code: identity ? undefined : 'AUTH' })
|
|
132
|
-
}`,
|
|
136
|
+
whoamiScript,
|
|
133
137
|
historyScript, detailScript, fallbackScript: domFallbackScript,
|
|
134
138
|
})
|