deck-plugin-sdk 0.15.1

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.
Files changed (45) hide show
  1. package/README.md +77 -0
  2. package/bin/deck-plugin.mjs +117 -0
  3. package/build-plugin.mjs +143 -0
  4. package/package.json +42 -0
  5. package/shim/bridge.d.ts +5 -0
  6. package/shim/bridge.js +196 -0
  7. package/shim/event.d.ts +5 -0
  8. package/shim/event.js +5 -0
  9. package/shim/jsx-runtime.js +20 -0
  10. package/shim/mcp.d.ts +68 -0
  11. package/shim/monaco.d.ts +5 -0
  12. package/shim/monaco.js +15 -0
  13. package/shim/react.js +50 -0
  14. package/shim/settings.d.ts +5 -0
  15. package/shim/settings.js +13 -0
  16. package/shim/terminals.d.ts +4 -0
  17. package/shim/terminals.js +70 -0
  18. package/shim/ui.d.ts +14 -0
  19. package/shim/ui.js +37 -0
  20. package/template/README.md +17 -0
  21. package/template/gitignore +4 -0
  22. package/template/package.json +10 -0
  23. package/template/plugin.json +8 -0
  24. package/template/src/plugin.tsx +65 -0
  25. package/template/tsconfig.json +13 -0
  26. package/types/components/ConfirmDialog.d.ts +22 -0
  27. package/types/components/ContextMenu.d.ts +41 -0
  28. package/types/components/MarkdownToolbar.d.ts +48 -0
  29. package/types/components/NamePrompt.d.ts +16 -0
  30. package/types/components/TabStrip.d.ts +26 -0
  31. package/types/components/Toast.d.ts +48 -0
  32. package/types/components/TreeRow.d.ts +41 -0
  33. package/types/components/dragrow.d.ts +34 -0
  34. package/types/components/menuplace.d.ts +30 -0
  35. package/types/components/ui.d.ts +102 -0
  36. package/types/components/useResize.d.ts +24 -0
  37. package/types/core/bridge.d.ts +670 -0
  38. package/types/core/editorsettings.d.ts +60 -0
  39. package/types/core/langmap.d.ts +15 -0
  40. package/types/core/monaco.d.ts +36 -0
  41. package/types/core/settingsstore.d.ts +19 -0
  42. package/types/core/shellpath.d.ts +45 -0
  43. package/types/core/terminals.d.ts +322 -0
  44. package/types/core/theme.d.ts +68 -0
  45. package/types/modules/editor/MarkdownLive.d.ts +61 -0
package/shim/mcp.d.ts ADDED
@@ -0,0 +1,68 @@
1
+ // GENERATED by sdk/gen-shim.mjs — do not edit.
2
+ //
3
+ // What a plugin's mcp.ts is handed. Type-only: none of this exists at run time, because the MCP
4
+ // server passes the real implementations in. See mcp/src/plugin-api.ts for the values.
5
+ import type { z as Zod } from "zod";
6
+
7
+ /** One tool's reply. */
8
+ export interface ToolReply { content: { type: "text"; text: string }[] }
9
+
10
+ /**
11
+ * The MCP server, narrowed to what a plugin uses: registering tools.
12
+ *
13
+ * The handler's argument is inferred FROM the schema — `{ url: z.string() }` gives the handler
14
+ * a `{ url: string }`. Typing it as `any` instead would compile just as happily and lose every
15
+ * field name inside the handler, which is the one place a typo costs something.
16
+ */
17
+ export interface McpServer {
18
+ tool<S extends Record<string, Zod.ZodTypeAny>>(
19
+ name: string,
20
+ description: string,
21
+ schema: S,
22
+ handler: (args: Zod.infer<Zod.ZodObject<S>>) => Promise<ToolReply> | ToolReply,
23
+ ): void;
24
+ }
25
+
26
+ export type Weekday =
27
+ | "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" | "Saturday" | "Sunday";
28
+
29
+ export interface ScriptJob {
30
+ id: string; name: string; command: string; args: string[];
31
+ mode: "interval" | "atTime"; intervalMin: number; days: string[]; timeOfDay: string;
32
+ enabled: boolean; lastRun: number; target?: string;
33
+ everyWeeks?: number; startDate?: string;
34
+ }
35
+ export interface ScriptFile { jobs: ScriptJob[] }
36
+
37
+ export interface Job {
38
+ id: string; module: string; label: string; mode: string; recurring: boolean;
39
+ days: Weekday[]; timeOfDay?: string; delayMin?: number; fireAt: number;
40
+ warned: boolean; payload: unknown;
41
+ }
42
+ export interface JobFile { jobs: Job[] }
43
+
44
+ export interface StartupProgram {
45
+ Name: string; Path: string; Args?: string[];
46
+ Days: string[]; Start: string; End: string; Enabled: boolean;
47
+ }
48
+
49
+ /** Everything the server hands a plugin's tools. */
50
+ export interface DeckMcp {
51
+ /** THIS server's zod — schemas must be built with it, never a bundled copy. */
52
+ z: typeof Zod;
53
+ ok: (text: string) => ToolReply;
54
+ weekday: Zod.ZodEnum<[Weekday, ...Weekday[]]>;
55
+ readJson: <T>(name: string, fallback: T) => T;
56
+ writeJson: (name: string, data: unknown) => void;
57
+ newId: () => string;
58
+ ALL_DAYS: Weekday[];
59
+ nextFire: (
60
+ spec: { mode: string; recurring: boolean; days: Weekday[]; timeOfDay?: string; fireAt: number },
61
+ now: number,
62
+ ) => number | null;
63
+ TIMER_MODULES: readonly ["app-closer", "power-timer"];
64
+ deckApi: (path: string, init?: RequestInit) => Promise<Response>;
65
+ apiErr: (e: unknown) => ToolReply;
66
+ }
67
+
68
+ export type RegisterTools = (server: McpServer, deck: DeckMcp) => void | Promise<void>;
@@ -0,0 +1,5 @@
1
+ // GENERATED by sdk/gen-shim.mjs — do not edit.
2
+ //
3
+ // Deck's real Monaco types, so a plugin is checked against the actual API rather than any.
4
+ import * as monaco from "monaco-editor";
5
+ export { monaco };
package/shim/monaco.js ADDED
@@ -0,0 +1,15 @@
1
+ // GENERATED by sdk/gen-shim.mjs — do not edit.
2
+ //
3
+ // Deck's Monaco. Resolved at USE time like the bridge: a plugin module is evaluated during
4
+ // loadPlugins, and a reference copied out at import time would capture a half-built object.
5
+ const m = () => {
6
+ const x = window.__deck?.monaco;
7
+ if (!x) throw new Error("window.__deck.monaco is missing — this plugin only runs inside Deck");
8
+ return x;
9
+ };
10
+
11
+ export const monaco = new Proxy({}, {
12
+ get: (_t, k) => m()[k],
13
+ ownKeys: () => Reflect.ownKeys(m()),
14
+ getOwnPropertyDescriptor: (_t, k) => ({ ...Object.getOwnPropertyDescriptor(m(), k), configurable: true }),
15
+ });
package/shim/react.js ADDED
@@ -0,0 +1,50 @@
1
+ // GENERATED by sdk/gen-shim.mjs — do not edit.
2
+ //
3
+ // Deck's React, not a second copy: two Reacts in one tree break hooks in ways that look like
4
+ // random render bugs.
5
+ const React = window.__deck.React;
6
+ export default React;
7
+ export const Activity = React.Activity;
8
+ export const Children = React.Children;
9
+ export const Component = React.Component;
10
+ export const Fragment = React.Fragment;
11
+ export const Profiler = React.Profiler;
12
+ export const PureComponent = React.PureComponent;
13
+ export const StrictMode = React.StrictMode;
14
+ export const Suspense = React.Suspense;
15
+ export const __CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
16
+ export const __COMPILER_RUNTIME = React.__COMPILER_RUNTIME;
17
+ export const act = React.act;
18
+ export const cache = React.cache;
19
+ export const cacheSignal = React.cacheSignal;
20
+ export const captureOwnerStack = React.captureOwnerStack;
21
+ export const cloneElement = React.cloneElement;
22
+ export const createContext = React.createContext;
23
+ export const createElement = React.createElement;
24
+ export const createRef = React.createRef;
25
+ export const forwardRef = React.forwardRef;
26
+ export const isValidElement = React.isValidElement;
27
+ export const lazy = React.lazy;
28
+ export const memo = React.memo;
29
+ export const startTransition = React.startTransition;
30
+ export const unstable_useCacheRefresh = React.unstable_useCacheRefresh;
31
+ export const use = React.use;
32
+ export const useActionState = React.useActionState;
33
+ export const useCallback = React.useCallback;
34
+ export const useContext = React.useContext;
35
+ export const useDebugValue = React.useDebugValue;
36
+ export const useDeferredValue = React.useDeferredValue;
37
+ export const useEffect = React.useEffect;
38
+ export const useEffectEvent = React.useEffectEvent;
39
+ export const useId = React.useId;
40
+ export const useImperativeHandle = React.useImperativeHandle;
41
+ export const useInsertionEffect = React.useInsertionEffect;
42
+ export const useLayoutEffect = React.useLayoutEffect;
43
+ export const useMemo = React.useMemo;
44
+ export const useOptimistic = React.useOptimistic;
45
+ export const useReducer = React.useReducer;
46
+ export const useRef = React.useRef;
47
+ export const useState = React.useState;
48
+ export const useSyncExternalStore = React.useSyncExternalStore;
49
+ export const useTransition = React.useTransition;
50
+ export const version = React.version;
@@ -0,0 +1,5 @@
1
+ // GENERATED by sdk/gen-shim.mjs — do not edit.
2
+ //
3
+ // Deck's real settings types, so a plugin is checked against the actual shape.
4
+ export { useSettings, getSettings, saveSettings } from "../types/core/settingsstore";
5
+ export type { Settings } from "../types/core/bridge";
@@ -0,0 +1,13 @@
1
+ // GENERATED by sdk/gen-shim.mjs — do not edit.
2
+ //
3
+ // Deck's settings store. Use this ONLY for settings Deck itself defines and its Rust side reads;
4
+ // a plugin's own settings belong in its own config file via configRead/configWrite.
5
+ const s = () => {
6
+ const x = window.__deck?.settings;
7
+ if (!x) throw new Error("window.__deck.settings is missing — this plugin only runs inside Deck");
8
+ return x;
9
+ };
10
+
11
+ export const useSettings = (...a) => s().use(...a);
12
+ export const getSettings = (...a) => s().get(...a);
13
+ export const saveSettings = (...a) => s().save(...a);
@@ -0,0 +1,4 @@
1
+ // GENERATED by sdk/gen-shim.mjs — do not edit.
2
+ //
3
+ // Deck's real terminal types, so a plugin is checked against the actual layout shape.
4
+ export * from "../types/core/terminals";
@@ -0,0 +1,70 @@
1
+ // GENERATED by sdk/gen-shim.mjs — do not edit.
2
+ //
3
+ // Deck's terminal panes. Resolved at USE time like the bridge: a plugin module is evaluated
4
+ // during loadPlugins, and a reference copied out at import time would capture a half-built
5
+ // object. The layout store is shared, not copied — a second one would not know about the panes
6
+ // Deck already has open.
7
+ const t = () => {
8
+ const x = window.__deck?.terminals;
9
+ if (!x) throw new Error("window.__deck.terminals is missing — this plugin only runs inside Deck");
10
+ return x;
11
+ };
12
+
13
+ export const ZONE_BOARD = (...a) => t().ZONE_BOARD(...a);
14
+ export const activeWorkspaceCwd = (...a) => t().activeWorkspaceCwd(...a);
15
+ export const applyDtCommand = (...a) => t().applyDtCommand(...a);
16
+ export const applyTerminalLook = (...a) => t().applyTerminalLook(...a);
17
+ export const attach = (...a) => t().attach(...a);
18
+ export const bracketPaste = (...a) => t().bracketPaste(...a);
19
+ export const clearPane = (...a) => t().clearPane(...a);
20
+ export const closeLeaf = (...a) => t().closeLeaf(...a);
21
+ export const destroy = (...a) => t().destroy(...a);
22
+ export const findLeaf = (...a) => t().findLeaf(...a);
23
+ export const focusPane = (...a) => t().focusPane(...a);
24
+ export const getInstance = (...a) => t().getInstance(...a);
25
+ export const getLayout = (...a) => t().getLayout(...a);
26
+ export const insertBeside = (...a) => t().insertBeside(...a);
27
+ export const isPinned = (...a) => t().isPinned(...a);
28
+ export const isWorkspaceActive = (...a) => t().isWorkspaceActive(...a);
29
+ export const leafIds = (...a) => t().leafIds(...a);
30
+ export const loadLayoutOnce = (...a) => t().loadLayoutOnce(...a);
31
+ export const markAgentStarted = (...a) => t().markAgentStarted(...a);
32
+ export const moveLeaf = (...a) => t().moveLeaf(...a);
33
+ export const moveWorkspace = (...a) => t().moveWorkspace(...a);
34
+ export const moveZone = (...a) => t().moveZone(...a);
35
+ export const mutateLayout = (...a) => t().mutateLayout(...a);
36
+ export const nextZoneSpot = (...a) => t().nextZoneSpot(...a);
37
+ export const openTabInWorkspace = (...a) => t().openTabInWorkspace(...a);
38
+ export const paneCwd = (...a) => t().paneCwd(...a);
39
+ export const paneHasAgent = (...a) => t().paneHasAgent(...a);
40
+ export const paneLabel = (...a) => t().paneLabel(...a);
41
+ export const paneLines = (...a) => t().paneLines(...a);
42
+ export const paneLocation = (...a) => t().paneLocation(...a);
43
+ export const pasteInto = (...a) => t().pasteInto(...a);
44
+ export const publishLayout = (...a) => t().publishLayout(...a);
45
+ export const queueInput = (...a) => t().queueInput(...a);
46
+ export const refit = (...a) => t().refit(...a);
47
+ export const restartPane = (...a) => t().restartPane(...a);
48
+ export const sendInput = (...a) => t().sendInput(...a);
49
+ export const setLeafLabel = (...a) => t().setLeafLabel(...a);
50
+ export const setLeafView = (...a) => t().setLeafView(...a);
51
+ export const splitLeaf = (...a) => t().splitLeaf(...a);
52
+ export const suspendWorkspace = (...a) => t().suspendWorkspace(...a);
53
+ export const switchWorkspace = (...a) => t().switchWorkspace(...a);
54
+ export const termKill = (...a) => t().termKill(...a);
55
+ export const termList = (...a) => t().termList(...a);
56
+ export const termResize = (...a) => t().termResize(...a);
57
+ export const termScrollback = (...a) => t().termScrollback(...a);
58
+ export const termSpawn = (...a) => t().termSpawn(...a);
59
+ export const termSweepScrollback = (...a) => t().termSweepScrollback(...a);
60
+ export const termWrite = (...a) => t().termWrite(...a);
61
+ export const togglePin = (...a) => t().togglePin(...a);
62
+ export const useAgentPanesVersion = (...a) => t().useAgentPanesVersion(...a);
63
+ export const useLayout = (...a) => t().useLayout(...a);
64
+ export const usePinnedPanes = (...a) => t().usePinnedPanes(...a);
65
+ export const webglLimit = (...a) => t().webglLimit(...a);
66
+ export const workspaceByCwd = (...a) => t().workspaceByCwd(...a);
67
+ export const workspaceShellCount = (...a) => t().workspaceShellCount(...a);
68
+ export const zoneAt = (...a) => t().zoneAt(...a);
69
+ export const zoneBoardFull = (...a) => t().zoneBoardFull(...a);
70
+ export const zoneToward = (...a) => t().zoneToward(...a);
package/shim/ui.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ // GENERATED by sdk/gen-shim.mjs — do not edit.
2
+ //
3
+ // Deck's real component types, so a plugin is checked against the actual props rather than any.
4
+ export * from "../types/components/ui";
5
+ export * from "../types/components/ConfirmDialog";
6
+ export * from "../types/components/NamePrompt";
7
+ export * from "../types/components/ContextMenu";
8
+ export * from "../types/components/Toast";
9
+ export * from "../types/components/useResize";
10
+ export * from "../types/modules/editor/MarkdownLive";
11
+ export * from "../types/components/TreeRow";
12
+ export * from "../types/components/dragrow";
13
+ export * from "../types/components/TabStrip";
14
+ export * from "../types/components/MarkdownToolbar";
package/shim/ui.js ADDED
@@ -0,0 +1,37 @@
1
+ // GENERATED by sdk/gen-shim.mjs — do not edit.
2
+ //
3
+ // Deck's own form controls. Resolved at USE time for the same reason the bridge is: a plugin
4
+ // module is evaluated during loadPlugins, and a reference copied out at import time would
5
+ // capture a half-built object.
6
+ const u = () => {
7
+ const x = window.__deck?.ui;
8
+ if (!x) throw new Error("window.__deck.ui is missing — this plugin only runs inside Deck");
9
+ return x;
10
+ };
11
+
12
+ export const ConfirmDialog = (...a) => u().ConfirmDialog(...a);
13
+ export const ContextMenu = (...a) => u().ContextMenu(...a);
14
+ export const DayPicker = (...a) => u().DayPicker(...a);
15
+ export const Field = (...a) => u().Field(...a);
16
+ export const GhostButton = (...a) => u().GhostButton(...a);
17
+ export const MarkdownLive = (...a) => u().MarkdownLive(...a);
18
+ export const MarkdownToolbar = (...a) => u().MarkdownToolbar(...a);
19
+ export const NamePrompt = (...a) => u().NamePrompt(...a);
20
+ export const PanelHead = (...a) => u().PanelHead(...a);
21
+ export const PrimaryButton = (...a) => u().PrimaryButton(...a);
22
+ export const Row = (...a) => u().Row(...a);
23
+ export const Segmented = (...a) => u().Segmented(...a);
24
+ export const Select = (...a) => u().Select(...a);
25
+ export const StatusItem = (...a) => u().StatusItem(...a);
26
+ export const StatusPopover = (...a) => u().StatusPopover(...a);
27
+ export const TabStrip = (...a) => u().TabStrip(...a);
28
+ export const Tabs = (...a) => u().Tabs(...a);
29
+ export const TextInput = (...a) => u().TextInput(...a);
30
+ export const TimeInput = (...a) => u().TimeInput(...a);
31
+ export const Toggle = (...a) => u().Toggle(...a);
32
+ export const TreeRow = (...a) => u().TreeRow(...a);
33
+ export const cmSurface = (...a) => u().cmSurface(...a);
34
+ export const rowAt = (...a) => u().rowAt(...a);
35
+ export const toast = (...a) => u().toast(...a);
36
+ export const useResize = (...a) => u().useResize(...a);
37
+ export const useRowDrag = (...a) => u().useRowDrag(...a);
@@ -0,0 +1,17 @@
1
+ # __NAME__
2
+
3
+ A plugin for [Deck](https://deck.hasan-zarif.com).
4
+
5
+ ## Developing
6
+
7
+ ```sh
8
+ npm run dev # build, and rebuild as you edit
9
+ npm run install-local # copy it into Deck, which loads it without a restart
10
+ ```
11
+
12
+ `src/plugin.tsx` is the entry point; its default export is the tab.
13
+
14
+ ## What it does
15
+
16
+ Say what this plugin is for. This file is what the registry shows on its page, so it is worth
17
+ writing for somebody deciding whether to install it rather than for yourself.
@@ -0,0 +1,4 @@
1
+ node_modules/
2
+ # Copied in by the build from the SDK — not yours to edit, and not worth committing.
3
+ shim/
4
+ types/
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "__ID__",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "build": "deck-plugin build",
7
+ "dev": "deck-plugin dev",
8
+ "install-local": "deck-plugin install"
9
+ }
10
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "id": "__ID__",
3
+ "name": "__NAME__",
4
+ "description": "One line on what this is for, shown under its name in Settings.",
5
+ "icon": "Sparkles",
6
+ "version": "0.1.0",
7
+ "minDeck": "0.15.0"
8
+ }
@@ -0,0 +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
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "jsx": "react-jsx",
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "skipLibCheck": true,
10
+ "lib": ["ES2022", "DOM"]
11
+ },
12
+ "include": ["src/**/*"]
13
+ }
@@ -0,0 +1,22 @@
1
+ // GENERATED by sdk/gen-types.mjs from Deck's source — do not edit.
2
+ export interface ConfirmState {
3
+ title: string;
4
+ /** A sentence for a plain question; nodes when the answer needs structure — an import summary
5
+ * listing what is about to be added, for instance. */
6
+ body?: React.ReactNode;
7
+ /** Defaults to "Confirm". */
8
+ confirmLabel?: string;
9
+ /** Red confirm button — for anything that destroys work. Default true. */
10
+ danger?: boolean;
11
+ /** Wider dialog, for a body that is a summary rather than a sentence. */
12
+ wide?: boolean;
13
+ /** Report something that already happened: one button, nothing to cancel. Replaces alert(),
14
+ * which in a webview is an OS modal — it steals focus, hides the cursor, and cannot be
15
+ * styled or dismissed with Escape. */
16
+ acknowledge?: boolean;
17
+ onConfirm: () => void;
18
+ }
19
+ export declare function ConfirmDialog({ state, onClose }: {
20
+ state: ConfirmState | null;
21
+ onClose: () => void;
22
+ }): import("react").JSX.Element;
@@ -0,0 +1,41 @@
1
+ // GENERATED by sdk/gen-types.mjs from Deck's source — do not edit.
2
+ import { type LucideIcon } from "lucide-react";
3
+ export interface MenuItem {
4
+ label: string;
5
+ /** Dim second line — a path, a description. Makes the row two-line. */
6
+ subLabel?: string;
7
+ icon?: LucideIcon;
8
+ hint?: string;
9
+ /** Status dot before the label: "ok" green, "warn" amber, "off" muted. */
10
+ dot?: "ok" | "warn" | "off";
11
+ danger?: boolean;
12
+ disabled?: boolean;
13
+ children?: MenuEntry[];
14
+ onClick?: () => void;
15
+ /** Icon button revealed on row hover — for a per-row action (close, delete) that would
16
+ * otherwise need a submenu. Its click never triggers the row's own onClick. */
17
+ action?: {
18
+ icon: LucideIcon;
19
+ title: string;
20
+ danger?: boolean;
21
+ onClick: () => void;
22
+ };
23
+ /** Set (with the menu's onReorder) to make this row drag-sortable. The value identifies the
24
+ * row to the caller — it's handed back as the moved id. */
25
+ dragId?: string;
26
+ /** A setting rather than an action: renders a checkbox and does NOT close the menu, so several
27
+ * can be flipped in one visit. The caller re-renders with the new value. */
28
+ checked?: boolean;
29
+ }
30
+ export type MenuEntry = MenuItem | "sep";
31
+ export declare function ContextMenu({ x, y, items, alignRight, onClose, onReorder, flipAt }: {
32
+ x: number;
33
+ y: number;
34
+ items: MenuEntry[];
35
+ alignRight?: boolean;
36
+ onClose: () => void;
37
+ /** A submenu flips around its parent row's LEFT edge, not the point it opened at. */
38
+ flipAt?: number;
39
+ /** Called with (draggedId, newIndexAmongDraggableRows) after a drag-sort. */
40
+ onReorder?: (id: string, toIndex: number) => void;
41
+ }): import("react").ReactPortal;
@@ -0,0 +1,48 @@
1
+ // GENERATED by sdk/gen-types.mjs from Deck's source — do not edit.
2
+ import type { EditorView } from "@codemirror/view";
3
+ /**
4
+ * The four things every button needs from an editor, so the buttons are written once and work
5
+ * over both of Deck's markdown surfaces: CodeMirror (Live) and Monaco (Split's raw pane).
6
+ *
7
+ * Everything is expressed as offsets into the document string. Both editors can convert to and
8
+ * from that, and it keeps the button logic free of either one's Position/Range types.
9
+ */
10
+ export interface TextSurface {
11
+ text(): string;
12
+ /** Current selection as document offsets. */
13
+ selection(): {
14
+ from: number;
15
+ to: number;
16
+ };
17
+ /** Apply edits and optionally move the selection. Must be ONE undo step. */
18
+ apply(changes: {
19
+ from: number;
20
+ to: number;
21
+ insert: string;
22
+ }[], select?: {
23
+ from: number;
24
+ to: number;
25
+ }): void;
26
+ focus(): void;
27
+ }
28
+ /** A TextSurface over a CodeMirror EditorView. */
29
+ export declare function cmSurface(view: EditorView): TextSurface;
30
+ export declare function MarkdownToolbar({ surface, zoom, onZoom, floating, view }: {
31
+ /** The editor to drive. Null disables every button — there is nothing to type into. */
32
+ surface: TextSurface | null;
33
+ /** Current text size in px. Omit to hide the zoom controls entirely. */
34
+ zoom?: number;
35
+ /** Called with +1 / -1 to step the size, and 0 to reset it. */
36
+ onZoom?: (delta: number) => void;
37
+ /**
38
+ * Float over the selection instead of sitting above the editor.
39
+ *
40
+ * Omit it and the editor's own "Floating markdown toolbar" setting decides, which is what
41
+ * every caller should do — this exists only for a surface that has a reason to override it.
42
+ * Needs `view`, which is what turns a document offset into screen coordinates.
43
+ */
44
+ floating?: boolean;
45
+ /** The CodeMirror view, for positioning a floating bar. Ignored otherwise. */
46
+ view?: EditorView | null;
47
+ }): import("react").JSX.Element;
48
+ export default MarkdownToolbar;
@@ -0,0 +1,16 @@
1
+ // GENERATED by sdk/gen-types.mjs from Deck's source — do not edit.
2
+ export interface NamePromptState {
3
+ title: string;
4
+ /** A second line under the title — the path being renamed, the ref being tagged. */
5
+ subtitle?: string;
6
+ /** Pre-filled value. A rename starts from the current name; a create starts empty. */
7
+ initial?: string;
8
+ placeholder?: string;
9
+ /** Defaults to "Save". */
10
+ confirmLabel?: string;
11
+ onSave: (value: string) => void;
12
+ }
13
+ export declare function NamePrompt({ state, onClose }: {
14
+ state: NamePromptState | null;
15
+ onClose: () => void;
16
+ }): import("react").JSX.Element;
@@ -0,0 +1,26 @@
1
+ // GENERATED by sdk/gen-types.mjs from Deck's source — do not edit.
2
+ import type { ReactNode } from "react";
3
+ export interface TabItem {
4
+ id: string;
5
+ title: ReactNode;
6
+ /** Drawn before the title — a file icon, an HTTP method, a kind glyph. */
7
+ icon?: ReactNode;
8
+ /** Unsaved changes: shows a dot that becomes the close X on hover. */
9
+ dirty?: boolean;
10
+ /** Rendered in italics — the editor's preview-tab convention. */
11
+ preview?: boolean;
12
+ /** Tooltip for the close button; defaults to "Close". */
13
+ closeTitle?: string;
14
+ }
15
+ export declare function TabStrip({ tabs, activeId, onSelect, onClose, onReorder, onDoubleClick, trailing, }: {
16
+ tabs: readonly TabItem[];
17
+ activeId: string | null;
18
+ onSelect: (id: string) => void;
19
+ onClose: (id: string) => void;
20
+ /** Moves `from` to `to`'s position. Omit to make the strip non-reorderable. */
21
+ onReorder?: (from: string, to: string) => void;
22
+ onDoubleClick?: (id: string) => void;
23
+ /** Right-aligned controls after the tabs — view toggles, save state. */
24
+ trailing?: ReactNode;
25
+ }): import("react").JSX.Element;
26
+ export default TabStrip;
@@ -0,0 +1,48 @@
1
+ // GENERATED by sdk/gen-types.mjs from Deck's source — do not edit.
2
+ export type FlashKind = "info" | "success" | "error";
3
+ export interface Flash {
4
+ id: number;
5
+ text: string;
6
+ kind: FlashKind;
7
+ /** Runs when the toast is clicked; the toast dismisses itself afterwards. */
8
+ onClick?: () => void;
9
+ /** Never expires on its own — see FlashOptions.ms. Exempt from the stack cap. */
10
+ sticky?: boolean;
11
+ }
12
+ /** The two things a caller may want to override per toast. Both optional. */
13
+ export interface FlashOptions {
14
+ /**
15
+ * Make the toast clickable.
16
+ *
17
+ * The stack is `pointer-events-none` so a toast never eats a click meant for the UI behind it;
18
+ * an item with a handler re-enables pointer events on itself alone.
19
+ */
20
+ onClick?: () => void;
21
+ /**
22
+ * How long it stays up, overriding the per-kind default.
23
+ *
24
+ * 0 means it does not expire: it stays until it is clicked, or until the caller calls the
25
+ * dismiss function `toast` returned. For something that is true for a while — a meeting about
26
+ * to start — a duration is the wrong shape, because the right one is "until it is no longer
27
+ * true" and the caller is what knows that.
28
+ */
29
+ ms?: number;
30
+ }
31
+ /**
32
+ * Show a toast. Returns a function that dismisses it.
33
+ *
34
+ * The return value is ignorable — `toast("Saved")` is still the whole usage for the ordinary
35
+ * case. It exists for a toast raised with `ms: 0`, which never expires on its own and so needs
36
+ * someone to take it down.
37
+ *
38
+ * Safe to call from anywhere, including a plugin and a module-level store, because the queue is
39
+ * not React state.
40
+ */
41
+ export declare function toast(text: string, kind?: FlashKind, opts?: FlashOptions): () => void;
42
+ /**
43
+ * The toast stack. Rendered once, by App.
44
+ *
45
+ * Bottom-centre, above the footer: the corners are taken (the footer's popovers open upward on
46
+ * the right) and the centre is where the eye already is after a click.
47
+ */
48
+ export declare function Toaster(): import("react").JSX.Element;