deck-plugin-sdk 1.2.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.
@@ -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 `plugins/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 "../shim/bridge.js";
9
-
10
- /** Where this plugin's own settings live. The `plugin-` prefix keeps them on this machine. */
11
- const CONFIG = "plugin-__ID__";
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
+ }
@@ -23,7 +23,7 @@ export declare function TimeInput({ value, onChange, className, }: {
23
23
  onChange: (v: string) => void;
24
24
  className?: string;
25
25
  }): import("react").JSX.Element;
26
- export declare function Select(props: React.SelectHTMLAttributes<HTMLSelectElement>): import("react").JSX.Element;
26
+ export declare function Select({ className, ...props }: React.SelectHTMLAttributes<HTMLSelectElement>): import("react").JSX.Element;
27
27
  export declare function PrimaryButton({ children, ...p }: React.ButtonHTMLAttributes<HTMLButtonElement>): import("react").JSX.Element;
28
28
  export declare function GhostButton({ children, ...p }: React.ButtonHTMLAttributes<HTMLButtonElement>): import("react").JSX.Element;
29
29
  /**
@@ -1,6 +1,6 @@
1
1
  // GENERATED by sdk/gen-types.mjs from Deck's source — do not edit.
2
2
  import { type DebugTarget } from "./debugtargets";
3
- import type { AccentColor, BgPreset, Density, TermTheme } from "./theme";
3
+ import type { Accent, Background, Density, Palette, TermCustom, TermTheme } from "./theme";
4
4
  /** Open a URL in the default browser. */
5
5
  export declare const openExternal: (url: string) => Promise<void>;
6
6
  export interface AppProc {
@@ -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
- export declare const getVaultRoot: () => Promise<string>;
16
- export declare const setVaultRoot: (path: string) => Promise<void>;
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.
@@ -44,12 +54,30 @@ export interface Settings {
44
54
  reduceMotion: boolean;
45
55
  /** The Servers list (hosts from ~/.ssh/config) under the workspace list. */
46
56
  serversList: boolean;
57
+ /** The mouse wheel over a tab bar switches tabs rather than scrolling the bar. */
58
+ tabWheelSwitch: boolean;
59
+ /** Install plugin and language updates at startup instead of only announcing them. */
60
+ pluginAutoUpdate: boolean;
47
61
  soundOnFire: boolean;
48
62
  playerPlacement: "fixed" | "floating";
49
- accent: AccentColor;
50
- bgPreset: BgPreset;
63
+ accent: Accent;
64
+ bgPreset: Background;
65
+ /** The colours of the "custom" background, each "#rrggbb". Kept when a preset is picked, so
66
+ * going back to Custom finds them again. */
67
+ customTheme?: Partial<Palette>;
68
+ /** Custom palettes the user saved by name, shown as cards beside the presets. */
69
+ savedThemes?: {
70
+ id: string;
71
+ name: string;
72
+ palette: Partial<Palette>;
73
+ }[];
74
+ /** The saved theme the custom colours came from, which edits are written back to. */
75
+ savedThemeId?: string;
51
76
  density: Density;
77
+ uiZoom: number;
52
78
  termTheme: TermTheme;
79
+ /** The "custom" terminal theme's colours. Kept when another theme is picked. */
80
+ termCustom?: Partial<TermCustom>;
53
81
  termFont: string;
54
82
  termFontSize: number;
55
83
  termScrollback: number;
@@ -75,6 +103,12 @@ export interface Settings {
75
103
  drawerHidden: string[];
76
104
  /** Drawer tabs left-to-right. Ids missing from it keep their discovery order, after the rest. */
77
105
  drawerOrder: string[];
106
+ /** Which side of the footer each drawer tab and readout sits on, in order (core/footerlayout.ts).
107
+ * Absent until something is moved: drawer tabs left, readouts right, in the orders above. */
108
+ footerLayout?: {
109
+ left: string[];
110
+ right: string[];
111
+ };
78
112
  httpMcpRevealSecrets: boolean;
79
113
  /**
80
114
  * What to call the user: shown to the others when sharing (a Canvas board's cursor and the
@@ -134,9 +168,6 @@ export interface MemUsage {
134
168
  export declare const memUsage: (detail?: boolean) => Promise<MemUsage>;
135
169
  export declare const listApps: () => Promise<AppProc[]>;
136
170
  export declare const listInstalled: () => Promise<AppProc[]>;
137
- export declare const closeApp: (target: string) => Promise<string>;
138
- export declare const openApp: (path: string) => Promise<void>;
139
- export declare const powerAction: (action: string) => Promise<void>;
140
171
  export declare const runScriptNow: (command: string, args: string[], id?: string, name?: string) => Promise<void>;
141
172
  export declare const pickScript: () => Promise<string>;
142
173
  export interface ExecOut {
@@ -150,12 +181,6 @@ export interface ExecOut {
150
181
  * something. A bare name goes through cmd.exe, so PATH and .bat shims (`flutter`, `npm`) work.
151
182
  */
152
183
  export declare const exec: (command: string, args?: string[], cwd?: string) => Promise<ExecOut>;
153
- export declare const notesScope: (cwd: string) => Promise<string>;
154
- export declare const notesList: (scope: string) => Promise<string[]>;
155
- export declare const notesRead: (scope: string, name: string) => Promise<string>;
156
- export declare const notesWrite: (scope: string, name: string, text: string) => Promise<void>;
157
- export declare const notesDelete: (scope: string, name: string) => Promise<void>;
158
- export declare const notesRename: (scope: string, from: string, to: string) => Promise<void>;
159
184
  /** One header, one value. A list rather than a map: order matters, and repeats are legal. */
160
185
  export type HttpHeader = [string, string];
161
186
  export interface HttpSendRequest {
@@ -195,19 +220,6 @@ export declare const httpCancel: (id: string) => Promise<void>;
195
220
  * reply under `job`. The Requests plugin listens for the event and does the send.
196
221
  */
197
222
  export declare const httpSendReply: (job: string, body: string) => Promise<void>;
198
- export interface DownloadItem {
199
- id: string;
200
- url: string;
201
- title: string;
202
- quality: string;
203
- format?: string;
204
- filePath?: string;
205
- sizeBytes?: number;
206
- status: "done" | "failed";
207
- at: number;
208
- }
209
- export declare const readDownloads: () => Promise<string>;
210
- export declare const writeDownloads: (json: string) => Promise<void>;
211
223
  export declare const pickFolder: () => Promise<string>;
212
224
  /** Native "save as" dialog. Returns "" when cancelled. */
213
225
  export declare const pickSavePath: (defaultName: string, ext: string) => Promise<string>;
@@ -222,7 +234,8 @@ export declare const pickImage: () => Promise<string>;
222
234
  export declare const setWallpaper: (src: string) => Promise<string>;
223
235
  export declare const clearWallpaper: () => Promise<void>;
224
236
  export declare const revealInFolder: (path: string) => Promise<void>;
225
- export declare const defaultDownloadDir: () => Promise<string>;
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>;
226
239
  export declare const openFile: (path: string) => Promise<void>;
227
240
  /** Files Deck was launched with — a double-click through Explorer's "Open with". */
228
241
  export declare const launchFiles: () => Promise<string[]>;
@@ -237,38 +250,7 @@ export interface TrackMeta {
237
250
  art_path: string;
238
251
  }
239
252
  export declare const readTrackMeta: (paths: string[]) => Promise<TrackMeta[]>;
240
- export interface MusicFolder {
241
- id: string;
242
- name: string;
243
- path: string;
244
- }
245
- export interface MusicPlaylist {
246
- id: string;
247
- name: string;
248
- tracks: string[];
249
- }
250
- export interface MusicLibrary {
251
- folders: MusicFolder[];
252
- favorites: string[];
253
- playlists: MusicPlaylist[];
254
- }
255
- export declare const EMPTY_LIBRARY: MusicLibrary;
256
- export declare const readLibrary: () => Promise<MusicLibrary>;
257
- export declare const writeLibrary: (lib: MusicLibrary) => Promise<void>;
258
253
  export { convertFileSrc } from "@tauri-apps/api/core";
259
- export interface SongSuggestion {
260
- id: string;
261
- title: string;
262
- artist: string;
263
- why: string;
264
- }
265
- export interface MusicSuggestions {
266
- generated_at: number;
267
- songs: SongSuggestion[];
268
- }
269
- export declare const readMusicSuggestions: () => Promise<MusicSuggestions | null>;
270
- export declare const readMusicTaste: () => Promise<string>;
271
- export declare const writeMusicTaste: (text: string) => Promise<void>;
272
254
  /** Start a sign-in. Returns the consent URL to open in the browser. */
273
255
  export declare const googleSignIn: () => Promise<string>;
274
256
  /** A valid access token, refreshed if needed. Rejects when not connected. */
@@ -349,8 +331,6 @@ export interface HistoryEntry {
349
331
  timeOfDay?: string;
350
332
  delayMin?: number;
351
333
  }
352
- export declare const historyDelete: (index: number) => Promise<void>;
353
- export declare const historyClear: (module: string) => Promise<void>;
354
334
  export interface StartupProgram {
355
335
  Name: string;
356
336
  Path: string;
@@ -360,11 +340,8 @@ export interface StartupProgram {
360
340
  End: string;
361
341
  Enabled: boolean;
362
342
  }
363
- export declare const startupRead: () => Promise<string>;
364
- export declare const startupWrite: (json: string) => Promise<void>;
365
343
  export declare const pickExe: () => Promise<string>;
366
344
  export declare const readTermLayout: <T>() => Promise<T | null>;
367
- export declare const writeTermLayout: (layout: unknown) => Promise<void>;
368
345
  /** `mtimeMs` is epoch ms, 0 if unreadable — lets a caller tell a settled file from one still being written. */
369
346
  export interface FsEntry {
370
347
  name: string;
@@ -402,7 +379,8 @@ export declare const remoteHome: (host: string, sudo: boolean) => Promise<string
402
379
  /** Host names from ~/.ssh/config, without patterns. */
403
380
  export declare const sshHosts: () => Promise<string[]>;
404
381
  export declare const fsWrite: (path: string, content: string) => Promise<void>;
405
- /** Raw bytes — saving a response that is an image or a PDF, which a string would corrupt. */
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. */
406
384
  export declare const fsWriteBytes: (path: string, bytes: Uint8Array) => Promise<void>;
407
385
  /** Write bytes without ever clobbering: dedupes the name on collision, returns the path used. */
408
386
  export declare const fsSaveUnique: (saveTo: string, defaultName: string, bytes: Uint8Array) => Promise<string>;
@@ -419,12 +397,10 @@ export declare const fsCreateFile: (dir: string, name: string) => Promise<string
419
397
  export declare const fsOpen: (path: string) => Promise<void>;
420
398
  /** The user's Downloads folder (home if there isn't one). */
421
399
  export declare const dirsDownload: () => Promise<string>;
422
- export declare const vaultResolve: (path: string) => Promise<string>;
423
- export declare const vaultRelativize: (path: string) => Promise<string>;
424
- export declare const vaultDataRead: (name: string) => Promise<string>;
425
- export declare const vaultDataWrite: (name: string, text: string) => Promise<void>;
426
400
  /** Relaunch Deck — the same binary, so a dev instance stays dev. Used by the plugin toggle. */
427
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>;
428
404
  /** Fetch the VPS's Script Runner run log over SSH into the local run-log-vps config (vpsjobs.rs). */
429
405
  export declare const vpsRunsPull: () => Promise<void>;
430
406
  /** What Rust saw of this launch, as Unix ms: process creation and the setup() span. Null until
@@ -449,8 +425,6 @@ export declare const backupExport: (path: string) => Promise<BackupSummary>;
449
425
  export declare const backupInspect: (path: string) => Promise<BackupSummary>;
450
426
  /** Writes the backup over this machine's copies. Deck should restart afterwards. */
451
427
  export declare const backupRestore: (path: string) => Promise<BackupSummary>;
452
- /** Copy a plugin folder into the plugins directory. Returns its id. Validates before writing. */
453
- export declare const installPlugin: (src: string) => Promise<string>;
454
428
  /** One file of a plugin, as the registry describes it. */
455
429
  export interface RemoteFile {
456
430
  url: string;
@@ -508,23 +482,35 @@ export declare const fsDelete: (path: string) => Promise<void>;
508
482
  export declare const fsTrash: (path: string) => Promise<void>;
509
483
  export declare const fsCopy: (src: string, dstDir: string) => Promise<string>;
510
484
  export declare const fsReveal: (path: string) => Promise<void>;
511
- export declare const installClaudeHooks: () => Promise<void>;
512
485
  /**
513
- * Deck's MCP server, which lets an agent drive Deck's terminals and HTTP client.
514
- *
515
- * The server ships with Deck as a single bundled file, so there is nothing to clone or install.
516
- * Registering it adds one entry to ~/.claude.json — a file that belongs to Claude Code, so Deck
517
- * backs it up first, merges rather than replaces, and refuses outright if it cannot parse it.
518
- *
519
- * `claudeMcpStatus` is "missing", "current", or "stale" — stale meaning an entry exists but
520
- * points somewhere else, which is what a reinstall to a different folder leaves behind.
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).
492
+ */
493
+ export declare const agentMcpStatus: (agent: string) => Promise<string>;
494
+ export declare const installAgentMcp: (agent: string) => Promise<string>;
495
+ /** Deck's hooks for an agent that has them ("claude", "codex"): what the Agents panel and the
496
+ * agent notifications hear from. Merged into the agent's own settings, backed up first. */
497
+ export declare const installAgentHooks: (agent: string) => Promise<void>;
498
+ /**
499
+ * Deck's skills (how to use its MCP tools) for an agent that reads skills: "claude" or "codex".
500
+ * Each comes back with what happened to it: "installed", "updated", "current", "kept-yours" (a
501
+ * skill of that name that is not Deck's) or "kept-edited" (Deck's, changed since). Deck only
502
+ * replaces a skill folder it wrote and nobody has edited.
521
503
  */
522
- export declare const claudeMcpStatus: () => Promise<string>;
523
- export declare const claudeMcpEntry: () => Promise<string>;
524
- export declare const installClaudeMcp: () => Promise<string>;
525
- export declare const removeClaudeMcp: () => Promise<void>;
526
- export declare const removeClaudeHooks: () => Promise<void>;
504
+ export declare const installAgentSkills: (agent: string) => Promise<{
505
+ skill: string;
506
+ outcome: string;
507
+ }[]>;
508
+ /** Which agent command-line tools are on PATH: any of claude, codex, gemini, cursor-agent, cursor. */
509
+ export declare const agentClis: () => Promise<string[]>;
527
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>;
528
514
  export declare const gitStatus: (dir: string) => Promise<GitStatusRow[]>;
529
515
  /** The repos a folder holds: the one it is inside first, then any below it. Each a repo's top level. */
530
516
  export declare const gitRepos: (dir: string) => Promise<string[]>;
@@ -536,7 +522,6 @@ export interface BlameLine {
536
522
  uncommitted: boolean;
537
523
  }
538
524
  export declare const gitBlameLine: (dir: string, rel: string, line: number, contents: string) => Promise<BlameLine | null>;
539
- export declare const gitHeadFile: (dir: string, rel: string) => Promise<string>;
540
525
  /** A blob's raw bytes. `rev` is "HEAD", or "" for the index. Empty = absent from that revision.
541
526
  * For content the text commands would corrupt: an image, a font. */
542
527
  export declare const gitFileBytes: (dir: string, rev: string, rel: string) => Promise<Uint8Array<ArrayBuffer>>;
@@ -552,10 +537,6 @@ export declare const gitPoll: (dir: string) => Promise<{
552
537
  rows: GitStatusRow[];
553
538
  info: GitInfo;
554
539
  }>;
555
- export declare const gitCommit: (dir: string, message: string) => Promise<string>;
556
- export declare const gitPush: (dir: string) => Promise<string>;
557
- export declare const gitPull: (dir: string) => Promise<string>;
558
- export declare const gitIndexFile: (dir: string, rel: string) => Promise<string>;
559
540
  export declare const gitFileDiff: (dir: string, rel: string) => Promise<string>;
560
541
  export interface ImportedPack {
561
542
  id: string;
@@ -565,9 +546,6 @@ export interface ImportedPack {
565
546
  export declare const importIconPack: (srcDir: string) => Promise<ImportedPack>;
566
547
  export declare const deleteIconPack: (id: string) => Promise<void>;
567
548
  export declare const readIconPackTheme: (path: string) => Promise<string>;
568
- export declare const gitStage: (dir: string, paths: string[]) => Promise<void>;
569
- export declare const gitStageContent: (dir: string, rel: string, content: string) => Promise<void>;
570
- export declare const gitUnstage: (dir: string, paths: string[]) => Promise<void>;
571
549
  export declare const gitDiscard: (dir: string, paths: string[]) => Promise<void>;
572
550
  export interface GraphCommit {
573
551
  hash: string;
@@ -589,14 +567,6 @@ export interface CommitFile {
589
567
  old?: string;
590
568
  }
591
569
  export declare const gitCommitFiles: (dir: string, hash: string) => Promise<CommitFile[]>;
592
- export declare const gitShowFile: (dir: string, rev: string, rel: string) => Promise<string>;
593
- export declare const gitPullRebase: (dir: string) => Promise<string>;
594
- export declare const gitFetch: (dir: string) => Promise<string>;
595
- export interface GitBranch {
596
- name: string;
597
- current: boolean;
598
- }
599
- export declare const gitBranches: (dir: string) => Promise<GitBranch[]>;
600
570
  export interface GitRef {
601
571
  kind: "local" | "remote" | "tag";
602
572
  name: string;
@@ -612,28 +582,6 @@ export declare const gitCheckoutNew: (dir: string, name: string) => Promise<stri
612
582
  export declare const gitCheckoutTrack: (dir: string, remote: string) => Promise<string>;
613
583
  export declare const gitCheckoutDetach: (dir: string, rev: string) => Promise<string>;
614
584
  export declare const gitAiCommitMsg: (dir: string, command: string, args: string, model: string) => Promise<string>;
615
- export declare const gitCommitAmend: (dir: string, message: string) => Promise<string>;
616
- export declare const gitUndoCommit: (dir: string) => Promise<string>;
617
- export declare const gitBranchAt: (dir: string, name: string, rev: string) => Promise<string>;
618
- export declare const gitRevert: (dir: string, rev: string) => Promise<string>;
619
- export declare const gitCherryPick: (dir: string, rev: string) => Promise<string>;
620
- export declare const gitResetTo: (dir: string, rev: string, mode: "soft" | "mixed" | "hard" | "keep") => Promise<string>;
621
- export declare const gitTag: (dir: string, name: string, rev: string, message?: string) => Promise<string>;
622
- export declare const gitMerge: (dir: string, rev: string, noFf?: boolean) => Promise<string>;
623
- /** Rebase the current branch onto `onto`; a conflict leaves it pending (gitPendingOp → "rebase"). */
624
- export declare const gitRebase: (dir: string, onto: string) => Promise<string>;
625
- /** HEAD's commit and branch ("" when detached) — what an undo returns to. */
626
- export declare const gitHead: (dir: string) => Promise<{
627
- hash: string;
628
- branch: string;
629
- }>;
630
- /** Merge `rev` into the current branch: a merge commit always, fast-forward when possible, or squashed into one commit. */
631
- export declare const gitMergeAs: (dir: string, rev: string, style: "no-ff" | "ff" | "squash") => Promise<string>;
632
- /** Finish a merge, rebase, revert or cherry-pick (what gitPendingOp reported) once its conflicts are staged. */
633
- export declare const gitContinueOp: (dir: string, op: string) => Promise<string>;
634
- /** Subjects of the commits on `head` that `base` lacks, oldest first. */
635
- export declare const gitRangeSubjects: (dir: string, base: string, head: string) => Promise<string[]>;
636
- export declare const gitRemoteUrl: (dir: string, name: string) => Promise<string>;
637
585
  /** The GitHub CLI, `gh pr …` or `gh repo view …` only. Rejects with "gh-missing" when gh is not installed. */
638
586
  export declare const ghRun: (dir: string, args: string[]) => Promise<string>;
639
587
  /** Pull request N's review threads, as GitHub's GraphQL JSON (parsed by prs.ts parseThreads). */
@@ -651,30 +599,6 @@ export declare const glabRun: (dir: string, args: string[]) => Promise<string>;
651
599
  export declare const glabApi: (dir: string, method: "GET" | "POST" | "PUT", path: string, fields?: [string, string][], json?: Record<string, object>) => Promise<string>;
652
600
  /** The files that differ between two revisions. */
653
601
  export declare const gitRangeFiles: (dir: string, from: string, to: string) => Promise<CommitFile[]>;
654
- export declare const gitMergeBase: (dir: string, a: string, b: string) => Promise<string>;
655
- /** Fetch pull request N's head from `remote`, so its commits can be diffed here. `gitlab`: a merge request's. */
656
- export declare const gitFetchPr: (dir: string, remote: string, number: number, base: string, gitlab?: boolean) => Promise<string>;
657
- export declare const gitBranchRename: (dir: string, from: string, to: string) => Promise<string>;
658
- export declare const gitPendingOp: (dir: string) => Promise<string>;
659
- export declare const gitAbortOp: (dir: string, op: string) => Promise<string>;
660
- export declare const gitBranchDelete: (dir: string, name: string, force?: boolean) => Promise<string>;
661
- export declare const gitBranchDeleteRemote: (dir: string, remote: string, name: string) => Promise<string>;
662
- export declare const gitTagDelete: (dir: string, name: string) => Promise<string>;
663
- export declare const gitTagPush: (dir: string, remote: string, name: string) => Promise<string>;
664
- export declare const gitTagDeleteRemote: (dir: string, remote: string, name: string) => Promise<string>;
665
- export declare const gitPushBranch: (dir: string, remote: string, name: string) => Promise<string>;
666
- export declare const gitRemotes: (dir: string) => Promise<string[]>;
667
- export interface GitStash {
668
- index: number;
669
- message: string;
670
- }
671
- export declare const gitStash: (dir: string, kind?: "" | "untracked" | "staged", message?: string) => Promise<string>;
672
- export declare const gitStashShow: (dir: string, index: number) => Promise<string>;
673
- export declare const gitStashList: (dir: string) => Promise<GitStash[]>;
674
- export declare const gitStashApply: (dir: string, index?: number) => Promise<string>;
675
- export declare const gitStashPop: (dir: string, index?: number) => Promise<string>;
676
- export declare const gitStashDrop: (dir: string, index?: number) => Promise<string>;
677
- export declare const gitStashClear: (dir: string) => Promise<string>;
678
602
  export interface SearchHit {
679
603
  path: string;
680
604
  rel: string;
@@ -760,7 +684,6 @@ export declare const dbSchema: (handle: number) => Promise<DbSchema>;
760
684
  /** Open a tunnel. `remote` is host:port as seen FROM `host`. Returns [id, local port]. */
761
685
  export declare const sshTunnelOpen: (host: string, remote: string) => Promise<[number, number]>;
762
686
  export declare const sshTunnelClose: (id: number) => Promise<void>;
763
- export declare const sshTunnelList: () => Promise<[number, number][]>;
764
687
  /**
765
688
  * Offer programs to the editor's debugger: a plugin that runs something debuggable (the Flutter
766
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;
@@ -1,5 +1,11 @@
1
1
  // GENERATED by sdk/gen-types.mjs from Deck's source — do not edit.
2
2
  import type * as MonacoNS from "monaco-editor";
3
+ /** What a language may set differently from the editor-wide value. Absent means "as everywhere". */
4
+ export interface LanguageOverride {
5
+ tabSize?: number;
6
+ insertSpaces?: boolean;
7
+ formatOnSave?: boolean;
8
+ }
3
9
  export interface EditorSettings {
4
10
  fontSize: number;
5
11
  fontFamily: string;
@@ -38,9 +44,32 @@ export interface EditorSettings {
38
44
  mouseWheelZoom: boolean;
39
45
  autoClosingBrackets: boolean;
40
46
  autoClosingQuotes: boolean;
47
+ /** When a file writes itself to disk. Off (the default) means only Ctrl+S saves. */
48
+ autoSave: "off" | "afterDelay" | "onFocusChange";
41
49
  autoSaveDelay: number;
42
50
  trimTrailingWhitespace: boolean;
43
51
  formatOnSave: boolean;
52
+ formatOnPaste: boolean;
53
+ /** Completion: popping up while typing, on a trigger character like ".", and what Enter does. */
54
+ quickSuggestions: boolean;
55
+ suggestOnTriggerCharacters: boolean;
56
+ acceptSuggestionOnEnter: "on" | "smart" | "off";
57
+ snippetSuggestions: "top" | "bottom" | "inline" | "none";
58
+ /** Renaming an HTML/JSX tag renames its closing tag as you type. */
59
+ linkedEditing: boolean;
60
+ /** Lines kept visible above and below the cursor when it moves near an edge. */
61
+ cursorSurroundingLines: number;
62
+ multiCursorModifier: "alt" | "ctrlCmd";
63
+ /** Copy or cut with nothing selected takes the whole line. */
64
+ emptySelectionClipboard: boolean;
65
+ /** The file tree: names or globs to hide (comma-separated), dotfiles, following the open file. */
66
+ treeHide: string;
67
+ treeShowDotfiles: boolean;
68
+ treeFollowActive: boolean;
69
+ /** The folders above what is in view stay pinned at the top of the tree while it scrolls. */
70
+ treeStickyScroll: boolean;
71
+ /** Per-language overrides, keyed by Monaco language id ("python", "typescript"). */
72
+ languageOverrides: Record<string, LanguageOverride>;
44
73
  formatLineLength: number;
45
74
  inlineErrors: boolean;
46
75
  inlineBlame: boolean;
@@ -66,4 +95,17 @@ export declare function getEditorSettings(): EditorSettings;
66
95
  /** For a store outside React that reacts to a setting (lsp.ts re-asks for inlay hints). */
67
96
  export declare function subscribeEditorSettings(cb: () => void): () => void;
68
97
  export declare function useEditorSettings(): EditorSettings;
98
+ /** A language's own value for each overridable setting, else the editor-wide one. */
99
+ export declare function forLanguage(s: EditorSettings, languageId: string | undefined): {
100
+ tabSize: number;
101
+ insertSpaces: boolean;
102
+ formatOnSave: boolean;
103
+ };
104
+ /** The model options for a file of `languageId`. */
105
+ export declare function modelOptionsFor(s: EditorSettings, languageId: string | undefined): {
106
+ tabSize: number;
107
+ insertSpaces: boolean;
108
+ };
109
+ /** Whether the file tree shows an entry, under these settings (core/treehide.ts). */
110
+ export declare const treeShows: (s: EditorSettings, name: string) => boolean;
69
111
  export declare function monacoOptionsFrom(s: EditorSettings): MonacoNS.editor.IEditorOptions;