deck-plugin-sdk 1.6.1 → 1.7.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.
@@ -36,6 +36,24 @@ export interface BrowserState {
36
36
  rotated: boolean;
37
37
  /** Devices shown side by side (DeviceBar), the first in the pane's own webview; [] for one. */
38
38
  devices: string[];
39
+ /** The page is not running: asleep after being out of sight, or put away from the memory
40
+ * readout. It wakes, or opens again, when the tab is shown. */
41
+ asleep: boolean;
42
+ /** The page's process crashed ("exited") or hangs ("unresponsive"); "" while it runs. */
43
+ crashed: "" | "exited" | "unresponsive";
44
+ /** An app link the page asked to open (mailto:, zoommtg:), and the site that asked, while the
45
+ * pane's bar waits for an answer; "" otherwise. */
46
+ appLink: string;
47
+ appOrigin: string;
48
+ /** A site's request to send notifications, waiting for the pane's bar (0 for none), and the site. */
49
+ permAsk: number;
50
+ permOrigin: string;
51
+ /** A site's sign-in or certificate error waiting for the address bar (0 for none): which, the
52
+ * address, and the realm or WebView2's error status. */
53
+ siteAsk: number;
54
+ siteKind: "" | "auth" | "cert";
55
+ siteUri: string;
56
+ siteDetail: string;
39
57
  }
40
58
  export declare const subscribeBrowser: (f: () => void) => () => void;
41
59
  export declare const browserState: (pane: string) => BrowserState | undefined;
@@ -73,6 +91,19 @@ export declare const totalBlocked: () => number;
73
91
  export declare const myFilters: () => Promise<string>;
74
92
  /** Save them, and put them to work. */
75
93
  export declare function saveMyFilters(text: string): Promise<void>;
94
+ /** The address bar's answer to a site's sign-in or certificate error. */
95
+ export declare function answerSite(pane: string, a: {
96
+ user?: string;
97
+ password?: string;
98
+ proceed?: boolean;
99
+ }): void;
100
+ /** The pane's bar: let the site send notifications, or not. */
101
+ export declare function answerPermission(pane: string, allow: boolean): void;
102
+ /** The pane's bar: open the app link it asked for, and with `always` for that site from now on. */
103
+ export declare function openAppLink(pane: string, always: boolean): Promise<void>;
104
+ export declare const dismissAppLink: (pane: string) => void;
105
+ /** "Wait" on a page that hangs: the bar goes, and comes back if WebView2 reports it again. */
106
+ export declare const dismissCrash: (pane: string) => void;
76
107
  /** Lay the pane's page out as a device (DeviceBar's ids), or as itself (""). */
77
108
  export declare const setDevice: (pane: string, device: string) => void;
78
109
  export declare const setRotated: (pane: string, rotated: boolean) => void;
@@ -186,4 +217,6 @@ export declare function noteTermOutput(pane: string, chunk: string): void;
186
217
  export declare function forgetTermPane(pane: string): void;
187
218
  /** Where a pane's page is on screen, in Deck's CSS pixels, while it shows one. */
188
219
  export declare const pageBox: (pane: string) => DOMRect | null;
220
+ /** Close the pane's webview to give back its memory, keeping the tab and its address. */
221
+ export declare function discardBrowserPane(pane: string): Promise<void>;
189
222
  export declare function trackBrowser(pane: string, el: HTMLElement, url: string): () => void;
@@ -24,6 +24,7 @@ export declare const normaliseExts: (exts: unknown) => string[];
24
24
  */
25
25
  export declare const fileOpeners: {
26
26
  id: string;
27
+ name: string;
27
28
  exts: string[];
28
29
  }[];
29
30
  /** The id of the plugin that opens `path` (by its extension), or undefined: the Editor's. */
@@ -52,3 +53,16 @@ export declare const fileUrl: (path: string) => string;
52
53
  * Editor, which the caller opens it in. Every way Deck opens a file asks this first.
53
54
  */
54
55
  export declare function openByType(path: string, hint?: Opener): boolean;
56
+ /**
57
+ * Everywhere `path` can open in Deck, for an Open with menu: the Editor, the browser (its types,
58
+ * on this PC), and each plugin that opens its type, named for the menu.
59
+ */
60
+ export declare function openersFor(path: string): {
61
+ to: Opener;
62
+ label: string;
63
+ }[];
64
+ /**
65
+ * Open `path` in `to` whatever the Files tab says, for an Open with menu. False for the Editor,
66
+ * which the caller opens it in (terminals' openInEditor).
67
+ */
68
+ export declare function openIn(path: string, to: Opener): boolean;
@@ -10,7 +10,7 @@
10
10
  * It is also what lets two bindings share a chord honestly — the editor's save and a terminal
11
11
  * action can both be Ctrl+S if the two surfaces never have the keyboard at the same time.
12
12
  */
13
- export type Scope = "app" | "workspaces" | "editor" | "terminal" | `plugin:${string}`;
13
+ export type Scope = "app" | "workspaces" | "editor" | "terminal" | "browser" | "markdown" | `plugin:${string}`;
14
14
  /** Which thing owns the chord. Absent means a plain window listener. */
15
15
  export type Surface = "monaco" | "xterm" | "codemirror";
16
16
  export interface KeyBinding {
@@ -65,6 +65,14 @@ export declare function conflict(bindings: readonly KeyBinding[], overrides: Ove
65
65
  export declare function scopeActive(scope: Scope, active: ReadonlySet<Scope>): boolean;
66
66
  /** The binding to run for an event, or null. Scope-aware, so the caller need not filter. */
67
67
  export declare function match(bindings: readonly KeyBinding[], overrides: Overrides, e: Parameters<typeof parseChord>[0], active: ReadonlySet<Scope>): KeyBinding | null;
68
+ /**
69
+ * The bindings in the order a key looks for its owner: every other scope before "app".
70
+ *
71
+ * "app" is always live, so if it came first in table order a pane's own binding for the same chord
72
+ * could never run: the PDF viewer's Ctrl+= zoomed the window, and F11 went to full screen when
73
+ * the debugger was paused on Step Into. The narrower scope is on screen to be asked first.
74
+ */
75
+ export declare function byScope(bindings: readonly KeyBinding[]): KeyBinding[];
68
76
  /**
69
77
  * A chord as Monaco's keycode bitmask, or null when Monaco has no code for it.
70
78
  *
@@ -20,6 +20,36 @@ export declare function resetOverrides(): Promise<void>;
20
20
  export declare function useKeybindings(): number;
21
21
  /** The chord in force for a binding, for a label or a tooltip. */
22
22
  export declare function chordFor(id: string): string;
23
+ /** The same, as a person reads it ("Ctrl+B"), for a tooltip or a menu hint; "" when unbound. */
24
+ export declare function keyOf(id: string): string;
25
+ /** A tooltip with the key in force after it: "Go back (Alt+←)", or the label alone when unbound. */
26
+ export declare function withKey(label: string, id: string): string;
27
+ /**
28
+ * Bind a registry binding inside one Monaco editor, and follow it when it is rebound in Settings.
29
+ *
30
+ * Monaco takes its keys before Deck's listener sees them, so a chord it hosts (Save) has to be
31
+ * handed to it. A one-off `addCommand` read the chord once, at mount: a rebind only reached the
32
+ * editors opened after it. An action can be disposed, so this swaps it whenever the chord changes.
33
+ * `monaco` is passed in so this file does not pull in monaco-editor. Returns the cleanup.
34
+ */
35
+ export declare function bindMonacoKey(ed: {
36
+ addAction(a: {
37
+ id: string;
38
+ label: string;
39
+ keybindings: number[];
40
+ run: () => void | Promise<void>;
41
+ }): {
42
+ dispose(): void;
43
+ };
44
+ }, monaco: {
45
+ KeyMod: {
46
+ CtrlCmd: number;
47
+ Alt: number;
48
+ Shift: number;
49
+ WinCtrl: number;
50
+ };
51
+ KeyCode: object;
52
+ }, id: string, run: () => void | Promise<void>): () => void;
23
53
  /**
24
54
  * An action, or an action with a `when` guard.
25
55
  *
@@ -43,6 +43,8 @@ export interface LayoutTab {
43
43
  * tab that has a cell to itself, which is every tab written before zones held several.
44
44
  */
45
45
  hidden?: boolean;
46
+ /** The tab group it is in (LayoutWorkspace.groups); a group's tabs sit together in one zone. */
47
+ group?: string;
46
48
  }
47
49
  export interface LayoutWorkspace {
48
50
  id: string;
@@ -50,6 +52,8 @@ export interface LayoutWorkspace {
50
52
  cwd: string;
51
53
  tabs: LayoutTab[];
52
54
  activeTab: string;
55
+ /** Tab groups: a name and colour over tabs that sit together in a zone's row, folded or not. */
56
+ groups?: TabGroup[];
53
57
  /** Its colour on the sidebar's collapsed rail, by index (Terminals' TONES); none picks one from the name. */
54
58
  color?: number;
55
59
  }
@@ -121,7 +125,53 @@ export declare function moveZone(tabs: readonly LayoutTab[], id: string, to: {
121
125
  * Every tab's cell is pinned first (placeAll): a tab with no stored position takes its cell from
122
126
  * its index, so reordering the list could otherwise move a zone you never touched.
123
127
  */
124
- export declare function reorderTab(tabs: readonly LayoutTab[], srcId: string, overId: string, after: boolean): LayoutTab[];
128
+ export declare function reorderTab(tabs: readonly LayoutTab[], srcId: string, overId: string, after: boolean,
129
+ /** A drag in the strip says which group the tab ends up in: the one of the tab it is held over
130
+ * (null: none, held over a tab outside any group or over a group's chip). Left out, the tabs
131
+ * either side decide (settleGroup). */
132
+ group?: string | null): LayoutTab[];
133
+ /** A tab group: its tabs carry its id. Its colour is an index into GROUP_COLORS. */
134
+ export interface TabGroup {
135
+ id: string;
136
+ name: string;
137
+ color: number;
138
+ folded?: boolean;
139
+ }
140
+ /** Chrome's group colours, tuned for Deck's dark surfaces. */
141
+ export declare const GROUP_COLORS: string[];
142
+ /**
143
+ * Put a tab in a group: `groupId`, or a new one in the next colour not yet used (its id is
144
+ * returned, so its editor can open). The tab moves next to the group's other tabs.
145
+ */
146
+ export declare function addToGroup(w: LayoutWorkspace, tabId: string, groupId?: string): {
147
+ w: LayoutWorkspace;
148
+ groupId: string;
149
+ };
150
+ /** Take a tab out of its group, to just after the group's tabs. */
151
+ export declare function leaveGroup(w: LayoutWorkspace, tabId: string): LayoutWorkspace;
152
+ /**
153
+ * Move a whole group, its tabs in their order, to just before or after `overId`. Over another
154
+ * group's tab it goes before or after that group as a whole, never into the middle of it.
155
+ */
156
+ export declare function moveGroup(tabs: readonly LayoutTab[], groupId: string, overId: string, after: boolean): LayoutTab[];
157
+ /**
158
+ * Fold a group, or open it. A group holding the tab its zone shows is not folded over it: the
159
+ * zone moves to the nearest tab outside the group that is not itself folded away (after the group
160
+ * first, then before it). With none, `makeTab` gives a new tab for the zone to open on; without
161
+ * it, the group stays open.
162
+ */
163
+ export declare function toggleGroupFold(w: LayoutWorkspace, groupId: string, makeTab?: () => LayoutTab): LayoutWorkspace;
164
+ /** The group goes; its tabs stay where they are. */
165
+ export declare function ungroup(w: LayoutWorkspace, groupId: string): LayoutWorkspace;
166
+ /** Change a group's name, colour or fold. */
167
+ export declare function setGroup(w: LayoutWorkspace, groupId: string, patch: Partial<Omit<TabGroup, "id">>): LayoutWorkspace;
168
+ /**
169
+ * The open tab is never folded away: however it came to be open (the tab beside a closed one, the
170
+ * switcher, a shortcut, an agent's notification), a folded group holding it opens.
171
+ */
172
+ export declare function openActiveGroup(w: LayoutWorkspace): LayoutWorkspace;
173
+ /** A group with no tabs left goes (its last tab closed, moved to another zone, taken out). */
174
+ export declare function pruneGroups(w: LayoutWorkspace): LayoutWorkspace;
125
175
  /**
126
176
  * Move one tab to another zone's cell — joining the zone there as the tab it shows, or making a
127
177
  * new zone in an empty cell. The zone it left keeps its other tabs.
@@ -147,8 +197,9 @@ export declare function addTabToZone(tabs: readonly LayoutTab[], besideId: strin
147
197
  */
148
198
  export declare function showActiveTab(w: LayoutWorkspace): LayoutWorkspace;
149
199
  /**
150
- * Which tab becomes active when `closing` goes: another tab in the same zone if it has one, so
151
- * closing a tab does not also throw you out of the zone; otherwise the first zone left.
200
+ * Which tab becomes active when `closing` goes: the one beside it in the same zone (the next, or
201
+ * the one before when it was last), as a browser does, so closing a tab neither throws you out of
202
+ * the zone nor back to its first tab; otherwise the first zone left.
152
203
  */
153
204
  export declare function nextActiveAfterClose(tabs: readonly LayoutTab[], closing: string): string | undefined;
154
205
  /** The first free spot on the top row, for a zone created without a position of its own. */
@@ -186,6 +237,11 @@ export declare function paneLocation(paneId: string): {
186
237
  wsName: string;
187
238
  tabId: string;
188
239
  } | undefined;
240
+ /**
241
+ * Go to a pane: switch to its workspace and tab, then focus it. The pane only mounts once
242
+ * Terminals has rendered the newly-selected tab, so the focus is retried across a few frames.
243
+ */
244
+ export declare function revealPane(paneId: string): boolean;
189
245
  /** Give a pane real keyboard focus. No-op if it isn't mounted yet — the caller retries. */
190
246
  export declare function focusPane(paneId: string): boolean;
191
247
  export declare const termSpawn: (id: string, cwd: string, cols: number, rows: number) => Promise<void>;
@@ -307,6 +363,8 @@ export declare function paneLines(id: string, max?: number): string[];
307
363
  * PDF plugin), otherwise in this workspace's Editor, at `line` when given.
308
364
  */
309
365
  export declare function openFile(path: string, line?: number): void;
366
+ /** Open a file in this workspace's Editor, whatever opens its type elsewhere (Open with › Editor). */
367
+ export declare function openInEditor(path: string, line?: number): void;
310
368
  export declare function getInstance(id: string): Instance;
311
369
  /**
312
370
  * Wrap pasted text in bracketed-paste markers, so the receiving app can tell one paste from
@@ -384,6 +442,18 @@ export declare function refit(id: string): void;
384
442
  * (Claude, vim) treats it as a repaint. Terminal and shell stay in agreement either way.
385
443
  */
386
444
  export declare function clearPane(id: string): void;
445
+ /**
446
+ * Stop the claude or codex in a pane: asked with Ctrl+C, so it tidies up and prints how to resume,
447
+ * and killed only if it stays (agent_stop in mem.rs), in which case its leftover modes are cleared.
448
+ */
449
+ export declare function stopPaneAgent(id: string): Promise<void>;
450
+ /**
451
+ * Turn off what a killed program left on in the pane's xterm: mouse reporting, focus events,
452
+ * bracketed paste, a hidden cursor. A program that exits turns these off itself; one killed
453
+ * never does, so every mouse move after it is typed into the shell. Only xterm is told (not the
454
+ * PTY), and unlike `term.reset()` the screen and scrollback stay.
455
+ */
456
+ export declare function resetPaneModes(id: string): void;
387
457
  /**
388
458
  * Kill the pane's shell and start a fresh one in the same xterm, keeping the pane id (so the
389
459
  * layout, name and split position survive). Claude is NOT re-resumed: `agentResumed` already
@@ -8,6 +8,8 @@ export declare const normPath: (p: string) => string;
8
8
  export declare const dirName: (p: string) => string;
9
9
  /** A repo as a picker names it: its path under `root`, or its own name when it is not under it. */
10
10
  export declare function repoLabel(root: string, repo: string): string;
11
+ /** The repo a path is in: the deepest of `repos` that holds it (a nested repo before its parent). */
12
+ export declare function repoOf(repos: readonly string[], path: string): string | undefined;
11
13
  export interface ChangeDir<T> {
12
14
  kind: "dir";
13
15
  name: string;