deck-plugin-sdk 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -77
- package/bin/deck-plugin.mjs +149 -116
- package/build-plugin.mjs +48 -26
- package/package.json +6 -1
- package/packages.mjs +107 -0
- package/shim/bridge.js +8 -90
- package/shim/event.js +6 -1
- package/shim/scope.js +6 -0
- package/shim/terminals.js +1 -0
- package/shim/ui.js +0 -1
- package/template/AGENTS.md +77 -0
- package/template/CLAUDE.md +1 -0
- package/template/README.md +20 -17
- package/template/gitignore +4 -4
- package/template/plugin.json +9 -9
- package/template/src/assets.d.ts +16 -0
- package/template/src/plugin.tsx +65 -65
- package/types/core/bridge.d.ts +27 -152
- package/types/core/editorsession.d.ts +50 -0
- package/types/core/fileview.d.ts +35 -0
- package/types/core/terminals.d.ts +5 -0
- package/types/modules/editor/DiffPeek.d.ts +19 -0
- package/types/modules/editor/MonacoHosts.d.ts +19 -6
- package/types/modules/editor/hunks.d.ts +54 -0
- package/types/modules/editor/tree.d.ts +0 -6
package/template/src/plugin.tsx
CHANGED
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
// __NAME__ — a Deck plugin.
|
|
2
|
-
//
|
|
3
|
-
// The default export is the tab. A plugin can export more than that — a footer readout, a
|
|
4
|
-
// settings panel, palette commands, a pane view — and `
|
|
5
|
-
// lists every slot. One export is enough to start.
|
|
6
|
-
import { useState } from "react";
|
|
7
|
-
import { Sparkles } from "lucide-react";
|
|
8
|
-
import { configRead, configWrite } from "
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
const CONFIG = "
|
|
12
|
-
|
|
13
|
-
export default function __COMPONENT__() {
|
|
14
|
-
const [note, setNote] = useState("");
|
|
15
|
-
const [saved, setSaved] = useState(false);
|
|
16
|
-
|
|
17
|
-
// Deck's config store, the same one its own modules use. Reading a key that has never been
|
|
18
|
-
// written resolves to an empty string rather than throwing.
|
|
19
|
-
const load = async () => {
|
|
20
|
-
const raw = await configRead(CONFIG).catch(() => "");
|
|
21
|
-
setNote(raw.trim() ? (JSON.parse(raw) as { note?: string }).note ?? "" : "");
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const save = async () => {
|
|
25
|
-
await configWrite(CONFIG, JSON.stringify({ note }));
|
|
26
|
-
setSaved(true);
|
|
27
|
-
setTimeout(() => setSaved(false), 1500);
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
return (
|
|
31
|
-
<div className="flex h-full flex-col gap-4 p-6">
|
|
32
|
-
<header className="flex items-center gap-3">
|
|
33
|
-
<Sparkles size={18} style={{ color: "var(--accent)" }} />
|
|
34
|
-
<h1 className="text-base font-semibold text-text-primary">__NAME__</h1>
|
|
35
|
-
</header>
|
|
36
|
-
|
|
37
|
-
<p className="max-w-[60ch] text-sm text-text-secondary">
|
|
38
|
-
Edit <code className="rounded bg-elev px-1.5 py-0.5 text-text-primary">src/plugin.tsx</code>,
|
|
39
|
-
run <code className="rounded bg-elev px-1.5 py-0.5 text-text-primary">npm run dev</code>,
|
|
40
|
-
and Deck reloads the plugin as you save.
|
|
41
|
-
</p>
|
|
42
|
-
|
|
43
|
-
<div className="flex max-w-md items-center gap-2">
|
|
44
|
-
<input
|
|
45
|
-
value={note}
|
|
46
|
-
onChange={(e) => setNote(e.target.value)}
|
|
47
|
-
onFocus={() => void load()}
|
|
48
|
-
placeholder="Type something, then save it"
|
|
49
|
-
className="min-w-0 flex-1 rounded-lg border border-subtle bg-elev px-3 py-2 text-sm text-text-primary outline-none focus:border-accent"
|
|
50
|
-
/>
|
|
51
|
-
<button
|
|
52
|
-
onClick={() => void save()}
|
|
53
|
-
className="shrink-0 rounded-lg border border-subtle bg-elev px-3 py-2 text-sm text-text-secondary hover:border-accent hover:text-text-primary"
|
|
54
|
-
>
|
|
55
|
-
{saved ? "Saved" : "Save"}
|
|
56
|
-
</button>
|
|
57
|
-
</div>
|
|
58
|
-
|
|
59
|
-
<p className="text-xs text-text-muted">
|
|
60
|
-
That writes to Deck's config store under <code>{CONFIG}</code>, which stays on this
|
|
61
|
-
machine.
|
|
62
|
-
</p>
|
|
63
|
-
</div>
|
|
64
|
-
);
|
|
65
|
-
}
|
|
1
|
+
// __NAME__ — a Deck plugin.
|
|
2
|
+
//
|
|
3
|
+
// The default export is the tab. A plugin can export more than that — a footer readout, a
|
|
4
|
+
// settings panel, palette commands, a pane view — and `docs/guide/api.md` in the Deck repository
|
|
5
|
+
// lists every slot. One export is enough to start.
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
import { Sparkles } from "lucide-react";
|
|
8
|
+
import { configRead, configWrite } from "deck-plugin-sdk/bridge";
|
|
9
|
+
|
|
10
|
+
/** This plugin's own settings. Deck keeps a plugin's configs in its own folder, so a plain name. */
|
|
11
|
+
const CONFIG = "settings";
|
|
12
|
+
|
|
13
|
+
export default function __COMPONENT__() {
|
|
14
|
+
const [note, setNote] = useState("");
|
|
15
|
+
const [saved, setSaved] = useState(false);
|
|
16
|
+
|
|
17
|
+
// Deck's config store, the same one its own modules use. Reading a key that has never been
|
|
18
|
+
// written resolves to an empty string rather than throwing.
|
|
19
|
+
const load = async () => {
|
|
20
|
+
const raw = await configRead(CONFIG).catch(() => "");
|
|
21
|
+
setNote(raw.trim() ? (JSON.parse(raw) as { note?: string }).note ?? "" : "");
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const save = async () => {
|
|
25
|
+
await configWrite(CONFIG, JSON.stringify({ note }));
|
|
26
|
+
setSaved(true);
|
|
27
|
+
setTimeout(() => setSaved(false), 1500);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<div className="flex h-full flex-col gap-4 p-6">
|
|
32
|
+
<header className="flex items-center gap-3">
|
|
33
|
+
<Sparkles size={18} style={{ color: "var(--accent)" }} />
|
|
34
|
+
<h1 className="text-base font-semibold text-text-primary">__NAME__</h1>
|
|
35
|
+
</header>
|
|
36
|
+
|
|
37
|
+
<p className="max-w-[60ch] text-sm text-text-secondary">
|
|
38
|
+
Edit <code className="rounded bg-elev px-1.5 py-0.5 text-text-primary">src/plugin.tsx</code>,
|
|
39
|
+
run <code className="rounded bg-elev px-1.5 py-0.5 text-text-primary">npm run dev</code>,
|
|
40
|
+
and Deck reloads the plugin as you save.
|
|
41
|
+
</p>
|
|
42
|
+
|
|
43
|
+
<div className="flex max-w-md items-center gap-2">
|
|
44
|
+
<input
|
|
45
|
+
value={note}
|
|
46
|
+
onChange={(e) => setNote(e.target.value)}
|
|
47
|
+
onFocus={() => void load()}
|
|
48
|
+
placeholder="Type something, then save it"
|
|
49
|
+
className="min-w-0 flex-1 rounded-lg border border-subtle bg-elev px-3 py-2 text-sm text-text-primary outline-none focus:border-accent"
|
|
50
|
+
/>
|
|
51
|
+
<button
|
|
52
|
+
onClick={() => void save()}
|
|
53
|
+
className="shrink-0 rounded-lg border border-subtle bg-elev px-3 py-2 text-sm text-text-secondary hover:border-accent hover:text-text-primary"
|
|
54
|
+
>
|
|
55
|
+
{saved ? "Saved" : "Save"}
|
|
56
|
+
</button>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<p className="text-xs text-text-muted">
|
|
60
|
+
That writes to Deck's config store under <code>{CONFIG}</code>, which stays on this
|
|
61
|
+
machine.
|
|
62
|
+
</p>
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|
package/types/core/bridge.d.ts
CHANGED
|
@@ -8,12 +8,22 @@ export interface AppProc {
|
|
|
8
8
|
title: string;
|
|
9
9
|
path: string;
|
|
10
10
|
}
|
|
11
|
+
/** A config's JSON text, "" when it does not exist yet. The name is its path in Deck's config folder
|
|
12
|
+
* without `.json`, folders and all: `settings/settings`, `state/term-procs`. A plugin names its
|
|
13
|
+
* own configs plainly (`boards`), and they are kept in `data/<plugin id>/`; one of Deck's own it
|
|
14
|
+
* names in full. `config-changed` names configs the same way, a plugin's own as it names them. */
|
|
11
15
|
export declare const configRead: (name: string) => Promise<string>;
|
|
12
16
|
/** Raw bytes rather than a JSON argument: a 13.8MB pinboard parsed as JSON on Deck's UI thread
|
|
13
17
|
* held every other command up for 200ms per save (see config_write in config.rs). */
|
|
18
|
+
/** The name is percent-encoded: it travels in a header, which is ASCII, and a name can be any text
|
|
19
|
+
* (a note's title). */
|
|
14
20
|
export declare const configWrite: (name: string, json: string) => Promise<void>;
|
|
15
|
-
|
|
16
|
-
export declare const
|
|
21
|
+
/** Remove a config or plain file, in order with the writes before it. */
|
|
22
|
+
export declare const configDelete: (name: string) => Promise<void>;
|
|
23
|
+
/** A plugin's own folder in Deck's config folder, `<config dir>\data\<id>`, for listing or
|
|
24
|
+
* renaming the files it keeps there with the fs* calls. A plugin calls it with no argument: its
|
|
25
|
+
* shim knows which plugin it is. */
|
|
26
|
+
export declare const dataDir: (plugin?: string) => Promise<string>;
|
|
17
27
|
/** The optional readouts in the footer status strip. */
|
|
18
28
|
/**
|
|
19
29
|
* A footer readout's id.
|
|
@@ -158,9 +168,6 @@ export interface MemUsage {
|
|
|
158
168
|
export declare const memUsage: (detail?: boolean) => Promise<MemUsage>;
|
|
159
169
|
export declare const listApps: () => Promise<AppProc[]>;
|
|
160
170
|
export declare const listInstalled: () => Promise<AppProc[]>;
|
|
161
|
-
export declare const closeApp: (target: string) => Promise<string>;
|
|
162
|
-
export declare const openApp: (path: string) => Promise<void>;
|
|
163
|
-
export declare const powerAction: (action: string) => Promise<void>;
|
|
164
171
|
export declare const runScriptNow: (command: string, args: string[], id?: string, name?: string) => Promise<void>;
|
|
165
172
|
export declare const pickScript: () => Promise<string>;
|
|
166
173
|
export interface ExecOut {
|
|
@@ -174,12 +181,6 @@ export interface ExecOut {
|
|
|
174
181
|
* something. A bare name goes through cmd.exe, so PATH and .bat shims (`flutter`, `npm`) work.
|
|
175
182
|
*/
|
|
176
183
|
export declare const exec: (command: string, args?: string[], cwd?: string) => Promise<ExecOut>;
|
|
177
|
-
export declare const notesScope: (cwd: string) => Promise<string>;
|
|
178
|
-
export declare const notesList: (scope: string) => Promise<string[]>;
|
|
179
|
-
export declare const notesRead: (scope: string, name: string) => Promise<string>;
|
|
180
|
-
export declare const notesWrite: (scope: string, name: string, text: string) => Promise<void>;
|
|
181
|
-
export declare const notesDelete: (scope: string, name: string) => Promise<void>;
|
|
182
|
-
export declare const notesRename: (scope: string, from: string, to: string) => Promise<void>;
|
|
183
184
|
/** One header, one value. A list rather than a map: order matters, and repeats are legal. */
|
|
184
185
|
export type HttpHeader = [string, string];
|
|
185
186
|
export interface HttpSendRequest {
|
|
@@ -219,19 +220,6 @@ export declare const httpCancel: (id: string) => Promise<void>;
|
|
|
219
220
|
* reply under `job`. The Requests plugin listens for the event and does the send.
|
|
220
221
|
*/
|
|
221
222
|
export declare const httpSendReply: (job: string, body: string) => Promise<void>;
|
|
222
|
-
export interface DownloadItem {
|
|
223
|
-
id: string;
|
|
224
|
-
url: string;
|
|
225
|
-
title: string;
|
|
226
|
-
quality: string;
|
|
227
|
-
format?: string;
|
|
228
|
-
filePath?: string;
|
|
229
|
-
sizeBytes?: number;
|
|
230
|
-
status: "done" | "failed";
|
|
231
|
-
at: number;
|
|
232
|
-
}
|
|
233
|
-
export declare const readDownloads: () => Promise<string>;
|
|
234
|
-
export declare const writeDownloads: (json: string) => Promise<void>;
|
|
235
223
|
export declare const pickFolder: () => Promise<string>;
|
|
236
224
|
/** Native "save as" dialog. Returns "" when cancelled. */
|
|
237
225
|
export declare const pickSavePath: (defaultName: string, ext: string) => Promise<string>;
|
|
@@ -246,7 +234,8 @@ export declare const pickImage: () => Promise<string>;
|
|
|
246
234
|
export declare const setWallpaper: (src: string) => Promise<string>;
|
|
247
235
|
export declare const clearWallpaper: () => Promise<void>;
|
|
248
236
|
export declare const revealInFolder: (path: string) => Promise<void>;
|
|
249
|
-
|
|
237
|
+
/** Deck's newest log file (`<config dir>\logs\deck-YYYY-MM-DD.log`), or the folder when empty. */
|
|
238
|
+
export declare const logLatest: () => Promise<string>;
|
|
250
239
|
export declare const openFile: (path: string) => Promise<void>;
|
|
251
240
|
/** Files Deck was launched with — a double-click through Explorer's "Open with". */
|
|
252
241
|
export declare const launchFiles: () => Promise<string[]>;
|
|
@@ -261,38 +250,7 @@ export interface TrackMeta {
|
|
|
261
250
|
art_path: string;
|
|
262
251
|
}
|
|
263
252
|
export declare const readTrackMeta: (paths: string[]) => Promise<TrackMeta[]>;
|
|
264
|
-
export interface MusicFolder {
|
|
265
|
-
id: string;
|
|
266
|
-
name: string;
|
|
267
|
-
path: string;
|
|
268
|
-
}
|
|
269
|
-
export interface MusicPlaylist {
|
|
270
|
-
id: string;
|
|
271
|
-
name: string;
|
|
272
|
-
tracks: string[];
|
|
273
|
-
}
|
|
274
|
-
export interface MusicLibrary {
|
|
275
|
-
folders: MusicFolder[];
|
|
276
|
-
favorites: string[];
|
|
277
|
-
playlists: MusicPlaylist[];
|
|
278
|
-
}
|
|
279
|
-
export declare const EMPTY_LIBRARY: MusicLibrary;
|
|
280
|
-
export declare const readLibrary: () => Promise<MusicLibrary>;
|
|
281
|
-
export declare const writeLibrary: (lib: MusicLibrary) => Promise<void>;
|
|
282
253
|
export { convertFileSrc } from "@tauri-apps/api/core";
|
|
283
|
-
export interface SongSuggestion {
|
|
284
|
-
id: string;
|
|
285
|
-
title: string;
|
|
286
|
-
artist: string;
|
|
287
|
-
why: string;
|
|
288
|
-
}
|
|
289
|
-
export interface MusicSuggestions {
|
|
290
|
-
generated_at: number;
|
|
291
|
-
songs: SongSuggestion[];
|
|
292
|
-
}
|
|
293
|
-
export declare const readMusicSuggestions: () => Promise<MusicSuggestions | null>;
|
|
294
|
-
export declare const readMusicTaste: () => Promise<string>;
|
|
295
|
-
export declare const writeMusicTaste: (text: string) => Promise<void>;
|
|
296
254
|
/** Start a sign-in. Returns the consent URL to open in the browser. */
|
|
297
255
|
export declare const googleSignIn: () => Promise<string>;
|
|
298
256
|
/** A valid access token, refreshed if needed. Rejects when not connected. */
|
|
@@ -373,8 +331,6 @@ export interface HistoryEntry {
|
|
|
373
331
|
timeOfDay?: string;
|
|
374
332
|
delayMin?: number;
|
|
375
333
|
}
|
|
376
|
-
export declare const historyDelete: (index: number) => Promise<void>;
|
|
377
|
-
export declare const historyClear: (module: string) => Promise<void>;
|
|
378
334
|
export interface StartupProgram {
|
|
379
335
|
Name: string;
|
|
380
336
|
Path: string;
|
|
@@ -384,11 +340,8 @@ export interface StartupProgram {
|
|
|
384
340
|
End: string;
|
|
385
341
|
Enabled: boolean;
|
|
386
342
|
}
|
|
387
|
-
export declare const startupRead: () => Promise<string>;
|
|
388
|
-
export declare const startupWrite: (json: string) => Promise<void>;
|
|
389
343
|
export declare const pickExe: () => Promise<string>;
|
|
390
344
|
export declare const readTermLayout: <T>() => Promise<T | null>;
|
|
391
|
-
export declare const writeTermLayout: (layout: unknown) => Promise<void>;
|
|
392
345
|
/** `mtimeMs` is epoch ms, 0 if unreadable — lets a caller tell a settled file from one still being written. */
|
|
393
346
|
export interface FsEntry {
|
|
394
347
|
name: string;
|
|
@@ -426,7 +379,8 @@ export declare const remoteHome: (host: string, sudo: boolean) => Promise<string
|
|
|
426
379
|
/** Host names from ~/.ssh/config, without patterns. */
|
|
427
380
|
export declare const sshHosts: () => Promise<string[]>;
|
|
428
381
|
export declare const fsWrite: (path: string, content: string) => Promise<void>;
|
|
429
|
-
/** Raw bytes —
|
|
382
|
+
/** Raw bytes — a PDF, an image, a response — which a string would corrupt. Sent as the raw body,
|
|
383
|
+
* the path percent-encoded in a header; a remote path writes over SSH. */
|
|
430
384
|
export declare const fsWriteBytes: (path: string, bytes: Uint8Array) => Promise<void>;
|
|
431
385
|
/** Write bytes without ever clobbering: dedupes the name on collision, returns the path used. */
|
|
432
386
|
export declare const fsSaveUnique: (saveTo: string, defaultName: string, bytes: Uint8Array) => Promise<string>;
|
|
@@ -443,12 +397,10 @@ export declare const fsCreateFile: (dir: string, name: string) => Promise<string
|
|
|
443
397
|
export declare const fsOpen: (path: string) => Promise<void>;
|
|
444
398
|
/** The user's Downloads folder (home if there isn't one). */
|
|
445
399
|
export declare const dirsDownload: () => Promise<string>;
|
|
446
|
-
export declare const vaultResolve: (path: string) => Promise<string>;
|
|
447
|
-
export declare const vaultRelativize: (path: string) => Promise<string>;
|
|
448
|
-
export declare const vaultDataRead: (name: string) => Promise<string>;
|
|
449
|
-
export declare const vaultDataWrite: (name: string, text: string) => Promise<void>;
|
|
450
400
|
/** Relaunch Deck — the same binary, so a dev instance stays dev. Used by the plugin toggle. */
|
|
451
401
|
export declare const restartApp: () => Promise<void>;
|
|
402
|
+
/** Start a test Deck (`deck.exe --test`) beside this one, or bring the running one forward. */
|
|
403
|
+
export declare const openTestDeck: () => Promise<void>;
|
|
452
404
|
/** Fetch the VPS's Script Runner run log over SSH into the local run-log-vps config (vpsjobs.rs). */
|
|
453
405
|
export declare const vpsRunsPull: () => Promise<void>;
|
|
454
406
|
/** What Rust saw of this launch, as Unix ms: process creation and the setup() span. Null until
|
|
@@ -473,8 +425,6 @@ export declare const backupExport: (path: string) => Promise<BackupSummary>;
|
|
|
473
425
|
export declare const backupInspect: (path: string) => Promise<BackupSummary>;
|
|
474
426
|
/** Writes the backup over this machine's copies. Deck should restart afterwards. */
|
|
475
427
|
export declare const backupRestore: (path: string) => Promise<BackupSummary>;
|
|
476
|
-
/** Copy a plugin folder into the plugins directory. Returns its id. Validates before writing. */
|
|
477
|
-
export declare const installPlugin: (src: string) => Promise<string>;
|
|
478
428
|
/** One file of a plugin, as the registry describes it. */
|
|
479
429
|
export interface RemoteFile {
|
|
480
430
|
url: string;
|
|
@@ -532,33 +482,19 @@ export declare const fsDelete: (path: string) => Promise<void>;
|
|
|
532
482
|
export declare const fsTrash: (path: string) => Promise<void>;
|
|
533
483
|
export declare const fsCopy: (src: string, dstDir: string) => Promise<string>;
|
|
534
484
|
export declare const fsReveal: (path: string) => Promise<void>;
|
|
535
|
-
export declare const installClaudeHooks: () => Promise<void>;
|
|
536
|
-
/**
|
|
537
|
-
* Deck's MCP server, which lets an agent drive Deck's terminals and HTTP client.
|
|
538
|
-
*
|
|
539
|
-
* The server ships with Deck as a single bundled file, so there is nothing to clone or install.
|
|
540
|
-
* Registering it adds one entry to ~/.claude.json — a file that belongs to Claude Code, so Deck
|
|
541
|
-
* backs it up first, merges rather than replaces, and refuses outright if it cannot parse it.
|
|
542
|
-
*
|
|
543
|
-
* `claudeMcpStatus` is "missing", "current", or "stale" — stale meaning an entry exists but
|
|
544
|
-
* points somewhere else, which is what a reinstall to a different folder leaves behind.
|
|
545
|
-
*/
|
|
546
|
-
export declare const claudeMcpStatus: () => Promise<string>;
|
|
547
|
-
export declare const claudeMcpEntry: () => Promise<string>;
|
|
548
|
-
export declare const installClaudeMcp: () => Promise<string>;
|
|
549
|
-
export declare const removeClaudeMcp: () => Promise<void>;
|
|
550
485
|
/**
|
|
551
|
-
*
|
|
552
|
-
*
|
|
553
|
-
*
|
|
486
|
+
* Deck's MCP server, which lets an agent drive Deck's terminals and HTTP client, registered with
|
|
487
|
+
* an AI coding agent: "claude", "codex", "gemini" or "cursor". The server ships with Deck as a
|
|
488
|
+
* single bundled file. Each agent keeps its MCP servers somewhere else (see agentmcp.rs), a file
|
|
489
|
+
* that belongs to that agent, so Deck backs it up first, merges rather than replaces, and refuses
|
|
490
|
+
* outright if it cannot parse it. The status is "missing", "current", "stale" (an entry pointing
|
|
491
|
+
* somewhere else, as a reinstall to another folder leaves) or "no-node" (nothing could run it).
|
|
554
492
|
*/
|
|
555
493
|
export declare const agentMcpStatus: (agent: string) => Promise<string>;
|
|
556
494
|
export declare const installAgentMcp: (agent: string) => Promise<string>;
|
|
557
|
-
export declare const removeAgentMcp: (agent: string) => Promise<void>;
|
|
558
495
|
/** Deck's hooks for an agent that has them ("claude", "codex"): what the Agents panel and the
|
|
559
496
|
* agent notifications hear from. Merged into the agent's own settings, backed up first. */
|
|
560
497
|
export declare const installAgentHooks: (agent: string) => Promise<void>;
|
|
561
|
-
export declare const removeAgentHooks: (agent: string) => Promise<void>;
|
|
562
498
|
/**
|
|
563
499
|
* Deck's skills (how to use its MCP tools) for an agent that reads skills: "claude" or "codex".
|
|
564
500
|
* Each comes back with what happened to it: "installed", "updated", "current", "kept-yours" (a
|
|
@@ -571,8 +507,10 @@ export declare const installAgentSkills: (agent: string) => Promise<{
|
|
|
571
507
|
}[]>;
|
|
572
508
|
/** Which agent command-line tools are on PATH: any of claude, codex, gemini, cursor-agent, cursor. */
|
|
573
509
|
export declare const agentClis: () => Promise<string[]>;
|
|
574
|
-
export declare const removeClaudeHooks: () => Promise<void>;
|
|
575
510
|
export declare const notifyOs: (title: string, body: string) => Promise<void>;
|
|
511
|
+
/** Run `git -C <dir> <args>`: its stdout, or what git said as the error. Never prompts for
|
|
512
|
+
* credentials. What the Git plugin builds its operations on. */
|
|
513
|
+
export declare const gitRun: (dir: string, args: string[]) => Promise<string>;
|
|
576
514
|
export declare const gitStatus: (dir: string) => Promise<GitStatusRow[]>;
|
|
577
515
|
/** The repos a folder holds: the one it is inside first, then any below it. Each a repo's top level. */
|
|
578
516
|
export declare const gitRepos: (dir: string) => Promise<string[]>;
|
|
@@ -584,7 +522,6 @@ export interface BlameLine {
|
|
|
584
522
|
uncommitted: boolean;
|
|
585
523
|
}
|
|
586
524
|
export declare const gitBlameLine: (dir: string, rel: string, line: number, contents: string) => Promise<BlameLine | null>;
|
|
587
|
-
export declare const gitHeadFile: (dir: string, rel: string) => Promise<string>;
|
|
588
525
|
/** A blob's raw bytes. `rev` is "HEAD", or "" for the index. Empty = absent from that revision.
|
|
589
526
|
* For content the text commands would corrupt: an image, a font. */
|
|
590
527
|
export declare const gitFileBytes: (dir: string, rev: string, rel: string) => Promise<Uint8Array<ArrayBuffer>>;
|
|
@@ -600,10 +537,6 @@ export declare const gitPoll: (dir: string) => Promise<{
|
|
|
600
537
|
rows: GitStatusRow[];
|
|
601
538
|
info: GitInfo;
|
|
602
539
|
}>;
|
|
603
|
-
export declare const gitCommit: (dir: string, message: string) => Promise<string>;
|
|
604
|
-
export declare const gitPush: (dir: string) => Promise<string>;
|
|
605
|
-
export declare const gitPull: (dir: string) => Promise<string>;
|
|
606
|
-
export declare const gitIndexFile: (dir: string, rel: string) => Promise<string>;
|
|
607
540
|
export declare const gitFileDiff: (dir: string, rel: string) => Promise<string>;
|
|
608
541
|
export interface ImportedPack {
|
|
609
542
|
id: string;
|
|
@@ -613,9 +546,6 @@ export interface ImportedPack {
|
|
|
613
546
|
export declare const importIconPack: (srcDir: string) => Promise<ImportedPack>;
|
|
614
547
|
export declare const deleteIconPack: (id: string) => Promise<void>;
|
|
615
548
|
export declare const readIconPackTheme: (path: string) => Promise<string>;
|
|
616
|
-
export declare const gitStage: (dir: string, paths: string[]) => Promise<void>;
|
|
617
|
-
export declare const gitStageContent: (dir: string, rel: string, content: string) => Promise<void>;
|
|
618
|
-
export declare const gitUnstage: (dir: string, paths: string[]) => Promise<void>;
|
|
619
549
|
export declare const gitDiscard: (dir: string, paths: string[]) => Promise<void>;
|
|
620
550
|
export interface GraphCommit {
|
|
621
551
|
hash: string;
|
|
@@ -637,14 +567,6 @@ export interface CommitFile {
|
|
|
637
567
|
old?: string;
|
|
638
568
|
}
|
|
639
569
|
export declare const gitCommitFiles: (dir: string, hash: string) => Promise<CommitFile[]>;
|
|
640
|
-
export declare const gitShowFile: (dir: string, rev: string, rel: string) => Promise<string>;
|
|
641
|
-
export declare const gitPullRebase: (dir: string) => Promise<string>;
|
|
642
|
-
export declare const gitFetch: (dir: string) => Promise<string>;
|
|
643
|
-
export interface GitBranch {
|
|
644
|
-
name: string;
|
|
645
|
-
current: boolean;
|
|
646
|
-
}
|
|
647
|
-
export declare const gitBranches: (dir: string) => Promise<GitBranch[]>;
|
|
648
570
|
export interface GitRef {
|
|
649
571
|
kind: "local" | "remote" | "tag";
|
|
650
572
|
name: string;
|
|
@@ -660,28 +582,6 @@ export declare const gitCheckoutNew: (dir: string, name: string) => Promise<stri
|
|
|
660
582
|
export declare const gitCheckoutTrack: (dir: string, remote: string) => Promise<string>;
|
|
661
583
|
export declare const gitCheckoutDetach: (dir: string, rev: string) => Promise<string>;
|
|
662
584
|
export declare const gitAiCommitMsg: (dir: string, command: string, args: string, model: string) => Promise<string>;
|
|
663
|
-
export declare const gitCommitAmend: (dir: string, message: string) => Promise<string>;
|
|
664
|
-
export declare const gitUndoCommit: (dir: string) => Promise<string>;
|
|
665
|
-
export declare const gitBranchAt: (dir: string, name: string, rev: string) => Promise<string>;
|
|
666
|
-
export declare const gitRevert: (dir: string, rev: string) => Promise<string>;
|
|
667
|
-
export declare const gitCherryPick: (dir: string, rev: string) => Promise<string>;
|
|
668
|
-
export declare const gitResetTo: (dir: string, rev: string, mode: "soft" | "mixed" | "hard" | "keep") => Promise<string>;
|
|
669
|
-
export declare const gitTag: (dir: string, name: string, rev: string, message?: string) => Promise<string>;
|
|
670
|
-
export declare const gitMerge: (dir: string, rev: string, noFf?: boolean) => Promise<string>;
|
|
671
|
-
/** Rebase the current branch onto `onto`; a conflict leaves it pending (gitPendingOp → "rebase"). */
|
|
672
|
-
export declare const gitRebase: (dir: string, onto: string) => Promise<string>;
|
|
673
|
-
/** HEAD's commit and branch ("" when detached) — what an undo returns to. */
|
|
674
|
-
export declare const gitHead: (dir: string) => Promise<{
|
|
675
|
-
hash: string;
|
|
676
|
-
branch: string;
|
|
677
|
-
}>;
|
|
678
|
-
/** Merge `rev` into the current branch: a merge commit always, fast-forward when possible, or squashed into one commit. */
|
|
679
|
-
export declare const gitMergeAs: (dir: string, rev: string, style: "no-ff" | "ff" | "squash") => Promise<string>;
|
|
680
|
-
/** Finish a merge, rebase, revert or cherry-pick (what gitPendingOp reported) once its conflicts are staged. */
|
|
681
|
-
export declare const gitContinueOp: (dir: string, op: string) => Promise<string>;
|
|
682
|
-
/** Subjects of the commits on `head` that `base` lacks, oldest first. */
|
|
683
|
-
export declare const gitRangeSubjects: (dir: string, base: string, head: string) => Promise<string[]>;
|
|
684
|
-
export declare const gitRemoteUrl: (dir: string, name: string) => Promise<string>;
|
|
685
585
|
/** The GitHub CLI, `gh pr …` or `gh repo view …` only. Rejects with "gh-missing" when gh is not installed. */
|
|
686
586
|
export declare const ghRun: (dir: string, args: string[]) => Promise<string>;
|
|
687
587
|
/** Pull request N's review threads, as GitHub's GraphQL JSON (parsed by prs.ts parseThreads). */
|
|
@@ -699,30 +599,6 @@ export declare const glabRun: (dir: string, args: string[]) => Promise<string>;
|
|
|
699
599
|
export declare const glabApi: (dir: string, method: "GET" | "POST" | "PUT", path: string, fields?: [string, string][], json?: Record<string, object>) => Promise<string>;
|
|
700
600
|
/** The files that differ between two revisions. */
|
|
701
601
|
export declare const gitRangeFiles: (dir: string, from: string, to: string) => Promise<CommitFile[]>;
|
|
702
|
-
export declare const gitMergeBase: (dir: string, a: string, b: string) => Promise<string>;
|
|
703
|
-
/** Fetch pull request N's head from `remote`, so its commits can be diffed here. `gitlab`: a merge request's. */
|
|
704
|
-
export declare const gitFetchPr: (dir: string, remote: string, number: number, base: string, gitlab?: boolean) => Promise<string>;
|
|
705
|
-
export declare const gitBranchRename: (dir: string, from: string, to: string) => Promise<string>;
|
|
706
|
-
export declare const gitPendingOp: (dir: string) => Promise<string>;
|
|
707
|
-
export declare const gitAbortOp: (dir: string, op: string) => Promise<string>;
|
|
708
|
-
export declare const gitBranchDelete: (dir: string, name: string, force?: boolean) => Promise<string>;
|
|
709
|
-
export declare const gitBranchDeleteRemote: (dir: string, remote: string, name: string) => Promise<string>;
|
|
710
|
-
export declare const gitTagDelete: (dir: string, name: string) => Promise<string>;
|
|
711
|
-
export declare const gitTagPush: (dir: string, remote: string, name: string) => Promise<string>;
|
|
712
|
-
export declare const gitTagDeleteRemote: (dir: string, remote: string, name: string) => Promise<string>;
|
|
713
|
-
export declare const gitPushBranch: (dir: string, remote: string, name: string) => Promise<string>;
|
|
714
|
-
export declare const gitRemotes: (dir: string) => Promise<string[]>;
|
|
715
|
-
export interface GitStash {
|
|
716
|
-
index: number;
|
|
717
|
-
message: string;
|
|
718
|
-
}
|
|
719
|
-
export declare const gitStash: (dir: string, kind?: "" | "untracked" | "staged", message?: string) => Promise<string>;
|
|
720
|
-
export declare const gitStashShow: (dir: string, index: number) => Promise<string>;
|
|
721
|
-
export declare const gitStashList: (dir: string) => Promise<GitStash[]>;
|
|
722
|
-
export declare const gitStashApply: (dir: string, index?: number) => Promise<string>;
|
|
723
|
-
export declare const gitStashPop: (dir: string, index?: number) => Promise<string>;
|
|
724
|
-
export declare const gitStashDrop: (dir: string, index?: number) => Promise<string>;
|
|
725
|
-
export declare const gitStashClear: (dir: string) => Promise<string>;
|
|
726
602
|
export interface SearchHit {
|
|
727
603
|
path: string;
|
|
728
604
|
rel: string;
|
|
@@ -808,7 +684,6 @@ export declare const dbSchema: (handle: number) => Promise<DbSchema>;
|
|
|
808
684
|
/** Open a tunnel. `remote` is host:port as seen FROM `host`. Returns [id, local port]. */
|
|
809
685
|
export declare const sshTunnelOpen: (host: string, remote: string) => Promise<[number, number]>;
|
|
810
686
|
export declare const sshTunnelClose: (id: number) => Promise<void>;
|
|
811
|
-
export declare const sshTunnelList: () => Promise<[number, number][]>;
|
|
812
687
|
/**
|
|
813
688
|
* Offer programs to the editor's debugger: a plugin that runs something debuggable (the Flutter
|
|
814
689
|
* plugin's runs) publishes them here, and the Run and Debug panel lists them to attach to. Pass
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// GENERATED by sdk/gen-types.mjs from Deck's source — do not edit.
|
|
2
|
+
export interface SessionTab {
|
|
3
|
+
/** Older sessions can also hold "graph" and "pr" tabs, from before git moved to the Git
|
|
4
|
+
* plugin. The Editor skips them on restore. */
|
|
5
|
+
kind: "file" | "media" | "graph" | "pr";
|
|
6
|
+
path: string;
|
|
7
|
+
rel: string | null;
|
|
8
|
+
dirty?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface WorkspaceSession {
|
|
11
|
+
tabs: SessionTab[];
|
|
12
|
+
activeId: string | null;
|
|
13
|
+
expanded: string[];
|
|
14
|
+
/** A typed-but-uncommitted message. Per root, because a message belongs to the repo it
|
|
15
|
+
* describes. Only the active module is mounted, so without this a half-written message is
|
|
16
|
+
* destroyed by switching to a terminal to check something — which is exactly when you switch. */
|
|
17
|
+
commitMsg?: string;
|
|
18
|
+
/** Collapsed Source Control rows: the two section headers, and folders in tree view. Per root
|
|
19
|
+
* because the keys are paths in this repo. A Set on the way in and out; an array here because
|
|
20
|
+
* that is what survives JSON. */
|
|
21
|
+
scmCollapsed?: string[];
|
|
22
|
+
}
|
|
23
|
+
/** A file to open, and optionally where in it to land. */
|
|
24
|
+
export interface PendingFile {
|
|
25
|
+
path: string;
|
|
26
|
+
line?: number;
|
|
27
|
+
}
|
|
28
|
+
export declare function queueOpenFiles(files: (string | PendingFile)[], instance?: EditorInstance): void;
|
|
29
|
+
/** Take everything queued for one editor, leaving its queue empty. */
|
|
30
|
+
export declare function drainOpenFiles(instance?: EditorInstance): PendingFile[];
|
|
31
|
+
/**
|
|
32
|
+
* Which editor is asking.
|
|
33
|
+
*
|
|
34
|
+
* There are two: the Editor tab, which opens whatever folder you point it at, and the one inside
|
|
35
|
+
* Terminals, which follows that workspace's cwd. They are separate windows onto different work,
|
|
36
|
+
* so their open folder and their UI prefs are stored per instance. Open TABS already separate on
|
|
37
|
+
* their own — loadSession is keyed by root, and the two rarely share one.
|
|
38
|
+
*/
|
|
39
|
+
export type EditorInstance = "tab" | "terminals";
|
|
40
|
+
export declare function loadEditorRoot(instance: EditorInstance): string;
|
|
41
|
+
export declare function saveEditorRoot(instance: EditorInstance, root: string): void;
|
|
42
|
+
export interface GlobalUi {
|
|
43
|
+
mdMode: "edit" | "live" | "split" | "preview";
|
|
44
|
+
panel: "explorer" | "search" | "debug" | "scm";
|
|
45
|
+
sidebarW: number;
|
|
46
|
+
}
|
|
47
|
+
export declare function loadSession(root: string): WorkspaceSession | null;
|
|
48
|
+
export declare function saveSession(root: string, s: WorkspaceSession): void;
|
|
49
|
+
export declare function loadUi(instance: EditorInstance): Partial<GlobalUi>;
|
|
50
|
+
export declare function saveUi(instance: EditorInstance, ui: GlobalUi): void;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// GENERATED by sdk/gen-types.mjs from Deck's source — do not edit.
|
|
2
|
+
/** The view showing `path` in plugin `pluginId`'s pane view. */
|
|
3
|
+
export declare const fileView: (pluginId: string, path: string) => string;
|
|
4
|
+
/** A view id's own part, and the file it was opened on if any. */
|
|
5
|
+
export declare function splitView(view: string): {
|
|
6
|
+
base: string;
|
|
7
|
+
file?: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* What two views are compared by, so one file is one tab however its path was spelled: the file
|
|
11
|
+
* tree, a terminal link and Quick Open can each give the same file with other slashes or case
|
|
12
|
+
* (Windows paths are case-insensitive). The stored view keeps the path as given, for the title.
|
|
13
|
+
*/
|
|
14
|
+
export declare function viewKey(view: string): string;
|
|
15
|
+
/** A path's extension, lowercased with its dot (".pdf"), or "" when it has none. */
|
|
16
|
+
export declare const extOf: (path: string) => string;
|
|
17
|
+
/** The last part of a path, for a tab's title. */
|
|
18
|
+
export declare const fileName: (path: string) => string;
|
|
19
|
+
/** Extensions as a plugin wrote them (".pdf", "PDF", "pdf"), as extOf returns them. */
|
|
20
|
+
export declare const normaliseExts: (exts: unknown) => string[];
|
|
21
|
+
/**
|
|
22
|
+
* Which loaded plugin opens which file types, from each plugin's `opens` export. Filled by the
|
|
23
|
+
* plugin loader (plugins.ts) on every load; here so that anything can ask without importing it.
|
|
24
|
+
*/
|
|
25
|
+
export declare const fileOpeners: {
|
|
26
|
+
id: string;
|
|
27
|
+
exts: string[];
|
|
28
|
+
}[];
|
|
29
|
+
/** The id of the plugin that opens `path` (by its extension), or undefined: the Editor's. */
|
|
30
|
+
export declare function pluginForFile(path: string): string | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Open `path` in the plugin that claims its type, as a tab of its own. False when no plugin does,
|
|
33
|
+
* so the caller opens it in the Editor as before. Every way Deck opens a file asks this first.
|
|
34
|
+
*/
|
|
35
|
+
export declare function openWithPlugin(path: string): boolean;
|
|
@@ -300,6 +300,11 @@ export declare function moveWorkspace(id: string, toIndex: number): void;
|
|
|
300
300
|
* Empty for a pane that has not spawned yet, which is the honest answer — there is nothing in it.
|
|
301
301
|
*/
|
|
302
302
|
export declare function paneLines(id: string, max?: number): string[];
|
|
303
|
+
/**
|
|
304
|
+
* Open a file in Deck the way its file tree does: in the plugin that opens its type (a .pdf in the
|
|
305
|
+
* PDF plugin), otherwise in this workspace's Editor, at `line` when given.
|
|
306
|
+
*/
|
|
307
|
+
export declare function openFile(path: string, line?: number): void;
|
|
303
308
|
export declare function getInstance(id: string): Instance;
|
|
304
309
|
/**
|
|
305
310
|
* Wrap pasted text in bracketed-paste markers, so the receiving app can tell one paste from
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// GENERATED by sdk/gen-types.mjs from Deck's source — do not edit.
|
|
2
|
+
import { type RefObject } from "react";
|
|
3
|
+
import { monaco } from "../../core/monaco";
|
|
4
|
+
import { type DirtyRange } from "./hunks";
|
|
5
|
+
/**
|
|
6
|
+
* The peek, for the editor in `edRef` showing `path` with the gutter's `ranges`. Returns what to
|
|
7
|
+
* render (a portal into the overlay), or null while closed.
|
|
8
|
+
*
|
|
9
|
+
* `clean` is whether the editor holds what is on disk: the changes are git's, read from disk, so
|
|
10
|
+
* their line numbers only fit the buffer when it has no unsaved edits. Staging and reverting wait
|
|
11
|
+
* for a save otherwise. `readBase` gives the text a change is against: the index's copy of the
|
|
12
|
+
* file for a change in the working tree, HEAD's for a staged one.
|
|
13
|
+
*/
|
|
14
|
+
export declare function useDiffPeek(edRef: RefObject<monaco.editor.IStandaloneCodeEditor | null>, path: string, ranges: DirtyRange[] | undefined, opts: {
|
|
15
|
+
clean: boolean;
|
|
16
|
+
onStage: (r: DirtyRange) => Promise<void>;
|
|
17
|
+
onUnstage: (r: DirtyRange) => Promise<void>;
|
|
18
|
+
readBase: (staged: boolean) => Promise<string>;
|
|
19
|
+
}): import("react").ReactPortal | null;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// GENERATED by sdk/gen-types.mjs from Deck's source — do not edit.
|
|
2
2
|
import { monaco } from "../../core/monaco";
|
|
3
3
|
import { type EditorSettings } from "../../core/editorsettings";
|
|
4
|
-
import type { DirtyRange } from "./
|
|
5
|
-
declare function MonacoEditorInner({ path, rel, value, onChange, onSave, gotoLine, gotoCol, gotoNonce, highlight, dirty, settings, onEditor }: {
|
|
4
|
+
import type { DirtyRange } from "./hunks";
|
|
5
|
+
declare function MonacoEditorInner({ path, rel, value, onChange, onSave, gotoLine, gotoCol, gotoNonce, highlight, dirty, settings, onEditor, clean, onStageChange, onUnstageChange, onReadBase }: {
|
|
6
6
|
path: string;
|
|
7
7
|
rel?: string | null;
|
|
8
8
|
value: string;
|
|
@@ -22,6 +22,13 @@ declare function MonacoEditorInner({ path, rel, value, onChange, onSave, gotoLin
|
|
|
22
22
|
/** Hands the live editor out, and null on unmount. For a formatting toolbar, which has to
|
|
23
23
|
* dispatch into this instance rather than rewrite the string around it. */
|
|
24
24
|
onEditor?: (e: monaco.editor.IStandaloneCodeEditor | null) => void;
|
|
25
|
+
/** The buffer matches the file on disk, which the gutter's changes were read from. */
|
|
26
|
+
clean?: boolean;
|
|
27
|
+
/** Stage or unstage one change from the gutter's peek (DiffPeek.tsx). */
|
|
28
|
+
onStageChange?: (r: DirtyRange) => Promise<void>;
|
|
29
|
+
onUnstageChange?: (r: DirtyRange) => Promise<void>;
|
|
30
|
+
/** The text the file's changes are against: the index's copy, or HEAD's for a staged change. */
|
|
31
|
+
onReadBase?: (staged: boolean) => Promise<string>;
|
|
25
32
|
}): import("react").JSX.Element;
|
|
26
33
|
/**
|
|
27
34
|
* Monaco owns its buffer, so this component re-rendering achieves nothing on its own — yet it was
|
|
@@ -35,13 +42,19 @@ declare function MonacoEditorInner({ path, rel, value, onChange, onSave, gotoLin
|
|
|
35
42
|
*/
|
|
36
43
|
export declare const MonacoEditor: import("react").MemoExoticComponent<typeof MonacoEditorInner>;
|
|
37
44
|
export declare function applyLineChanges(original: monaco.editor.ITextModel, modified: monaco.editor.ITextModel, diffs: monaco.editor.ILineChange[]): string;
|
|
45
|
+
type HunkRun = (change: monaco.editor.ILineChange, models: {
|
|
46
|
+
original: monaco.editor.ITextModel;
|
|
47
|
+
modified: monaco.editor.ITextModel;
|
|
48
|
+
}) => void;
|
|
49
|
+
/**
|
|
50
|
+
* Per-change buttons in a diff's gutter: stage (or unstage) one change, and, given `revert`, put
|
|
51
|
+
* one change back to the left side's text. Each change gets them at its first line.
|
|
52
|
+
*/
|
|
38
53
|
export interface HunkAction {
|
|
39
54
|
label: string;
|
|
40
55
|
unstage: boolean;
|
|
41
|
-
run:
|
|
42
|
-
|
|
43
|
-
modified: monaco.editor.ITextModel;
|
|
44
|
-
}) => void;
|
|
56
|
+
run: HunkRun;
|
|
57
|
+
revert?: HunkRun;
|
|
45
58
|
}
|
|
46
59
|
/** A side of a diff: LEFT the old version, RIGHT the new — GitHub's names, which line comments use. */
|
|
47
60
|
export type DiffSide = "LEFT" | "RIGHT";
|