dsh-claude-desktop-theme 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -6
- package/lib/client.js +7916 -5407
- package/lib/index.js +6 -6
- package/lib/types/client/compat/account-balance-hint.d.ts +11 -0
- package/lib/types/client/compat/account-balance.d.ts +2 -0
- package/lib/types/client/compat/conversation-stream.d.ts +5 -0
- package/lib/types/client/compat/files-pane.d.ts +2 -2
- package/lib/types/client/compat/header-menu-actions.d.ts +0 -2
- package/lib/types/client/compat/host-builds.d.ts +5 -4
- package/lib/types/client/compat/host-dom.d.ts +19 -2
- package/lib/types/client/compat/search-palette-port.d.ts +4 -0
- package/lib/types/client/compat/sidebar-editor.d.ts +32 -0
- package/lib/types/client/compat/sidebar-more-menu.d.ts +13 -0
- package/lib/types/client/compat/sidebar-navigation.d.ts +8 -0
- package/lib/types/client/compat/sidebar-panels.d.ts +62 -0
- package/lib/types/client/compat/sidebar-search.d.ts +13 -14
- package/lib/types/client/compat/workspace-menu.d.ts +2 -1
- package/lib/types/client/compat/workspace-worktree.d.ts +12 -2
- package/lib/types/client/contracts/ports.d.ts +102 -0
- package/lib/types/client/features/composer-pet/claude-frames.d.ts +2 -2
- package/lib/types/client/features/right-panel/mount.d.ts +5 -0
- package/lib/types/client/features/search-palette/SearchPalette.d.ts +23 -0
- package/lib/types/client/features/search-palette/model.d.ts +109 -0
- package/lib/types/client/features/search-palette/mount.d.ts +17 -0
- package/lib/types/client/features/settings/ColourMenu.d.ts +16 -0
- package/lib/types/client/features/settings/FontMenu.d.ts +1 -1
- package/lib/types/client/features/settings/ThemePanel.d.ts +21 -0
- package/lib/types/client/features/settings/colours.d.ts +8 -0
- package/lib/types/client/features/settings/fields.d.ts +6 -3
- package/lib/types/client/features/settings/locales.d.ts +16 -5
- package/lib/types/client/features/settings/mount.d.ts +7 -5
- package/lib/types/client/features/settings/register.d.ts +13 -2
- package/lib/types/client/features/sidebar/navigation-icons.d.ts +3 -0
- package/lib/types/client/features/sidebar-editor/MoreCardRows.d.ts +24 -0
- package/lib/types/client/features/sidebar-editor/SidebarEditor.d.ts +20 -0
- package/lib/types/client/features/sidebar-editor/copy.d.ts +9 -0
- package/lib/types/client/features/sidebar-editor/mount.d.ts +18 -0
- package/lib/types/client/features/sidebar-editor/state.d.ts +31 -0
- package/lib/types/client/theme/palette.d.ts +1 -1
- package/lib/types/host/index.d.ts +16 -16
- package/lib/types/shared/config.d.ts +4 -4
- package/lib/types/shared/identity.d.ts +1 -1
- package/package.json +16 -16
- package/lib/types/client/features/shell/index.d.ts +0 -14
package/lib/index.js
CHANGED
|
@@ -10,8 +10,8 @@ var DEFAULT_PERSONALIZATION = Object.freeze({
|
|
|
10
10
|
greetingName: ""
|
|
11
11
|
});
|
|
12
12
|
var DEFAULT_FEATURES = Object.freeze({
|
|
13
|
-
shell: true,
|
|
14
13
|
sidebar: true,
|
|
14
|
+
"right-panel": true,
|
|
15
15
|
"new-session": true,
|
|
16
16
|
conversation: true,
|
|
17
17
|
"tool-calls": true,
|
|
@@ -1258,11 +1258,11 @@ function mountWorktrees(ctx, enabled) {
|
|
|
1258
1258
|
var HEX_COLOUR = /^(#[0-9a-fA-F]{3}|#[0-9a-fA-F]{6})?$/;
|
|
1259
1259
|
var FONT_NAME = new RegExp(`^[\\p{L}\\p{N} ._-]{0,${FONT_NAME_MAX_LENGTH}}$`, "u");
|
|
1260
1260
|
var Config = z.object({
|
|
1261
|
-
enabled: z.boolean().default(false).description("\u542F
|
|
1261
|
+
enabled: z.boolean().default(false).description("\u5F00\u542F / \u5173\u95ED Claude \u4E3B\u9898").volatile(),
|
|
1262
1262
|
debug: z.boolean().default(false).description("\u5728\u63A7\u5236\u53F0\u8F93\u51FA\u8C03\u8BD5\u65E5\u5FD7").volatile(),
|
|
1263
1263
|
features: z.object({
|
|
1264
|
-
shell: z.boolean().default(DEFAULT_FEATURES.shell),
|
|
1265
1264
|
sidebar: z.boolean().default(DEFAULT_FEATURES.sidebar),
|
|
1265
|
+
"right-panel": z.boolean().default(DEFAULT_FEATURES["right-panel"]),
|
|
1266
1266
|
"new-session": z.boolean().default(DEFAULT_FEATURES["new-session"]),
|
|
1267
1267
|
conversation: z.boolean().default(DEFAULT_FEATURES.conversation),
|
|
1268
1268
|
"tool-calls": z.boolean().default(DEFAULT_FEATURES["tool-calls"]),
|
|
@@ -1286,10 +1286,10 @@ var Config = z.object({
|
|
|
1286
1286
|
code: z.string().default(DEFAULT_FONTS.code).description("\u4EE3\u7801\u4E0E\u7B49\u5BBD\u5B57\u4F53\u540D\uFF08\u7559\u7A7A\u7528\u7CFB\u7EDF\u6808\uFF09").pattern(FONT_NAME)
|
|
1287
1287
|
}).default({ ...DEFAULT_FONTS }).description("\u5B57\u4F53").volatile(),
|
|
1288
1288
|
personalization: z.object({
|
|
1289
|
-
petStyle: z.union(["whale", "claude"]).default(DEFAULT_PERSONALIZATION.petStyle).description("\u8F93\u5165\u6846\u5BA0\u7269\u6837\u5F0F"),
|
|
1289
|
+
petStyle: z.union(["whale", "claude", "none"]).default(DEFAULT_PERSONALIZATION.petStyle).description("\u8F93\u5165\u6846\u5BA0\u7269\u6837\u5F0F"),
|
|
1290
1290
|
runningStyle: z.union(["whale", "claude"]).default(DEFAULT_PERSONALIZATION.runningStyle).description("\u804A\u5929\u8F93\u51FA\u4E2D\u7684\u7B49\u5F85\u56FE\u6807\u4E0E\u72B6\u6001\u6837\u5F0F"),
|
|
1291
|
-
replySignatureStyle: z.union(["whale", "claude"]).default(DEFAULT_PERSONALIZATION.replySignatureStyle).description("\u56DE\u590D\u7ED3\u675F\u540E\u7684\u7B7E\u540D\u56FE\u6807\u6837\u5F0F"),
|
|
1292
|
-
greetingStyle: z.union(["explore", "claude"]).default(DEFAULT_PERSONALIZATION.greetingStyle).description("\u9996\u9875\u95EE\u5019\u8BED\u4E0E\u56FE\u6807\u6837\u5F0F"),
|
|
1291
|
+
replySignatureStyle: z.union(["whale", "claude", "none"]).default(DEFAULT_PERSONALIZATION.replySignatureStyle).description("\u56DE\u590D\u7ED3\u675F\u540E\u7684\u7B7E\u540D\u56FE\u6807\u6837\u5F0F"),
|
|
1292
|
+
greetingStyle: z.union(["explore", "claude", "none"]).default(DEFAULT_PERSONALIZATION.greetingStyle).description("\u9996\u9875\u95EE\u5019\u8BED\u4E0E\u56FE\u6807\u6837\u5F0F"),
|
|
1293
1293
|
greetingName: z.string().default("").pattern(/^.{0,64}$/u).description("\u95EE\u5019\u8BED\u4E2D\u7684\u79F0\u547C\uFF08\u53EF\u7559\u7A7A\uFF09")
|
|
1294
1294
|
}).default({ ...DEFAULT_PERSONALIZATION }).description("\u4E2A\u6027\u5316").volatile(),
|
|
1295
1295
|
view: z.object({
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Disposer } from '../contracts/ports.ts';
|
|
2
|
+
export interface AccountBalanceBreakdown {
|
|
3
|
+
total: string;
|
|
4
|
+
toppedUp: string;
|
|
5
|
+
granted: string;
|
|
6
|
+
}
|
|
7
|
+
/** The account menu owns this top-layer hint, including its delayed teardown. */
|
|
8
|
+
export declare function mountAccountBalanceHint(menu: HTMLElement, row: HTMLElement, zh: boolean): {
|
|
9
|
+
update: (balance: AccountBalanceBreakdown | undefined, message: string) => void;
|
|
10
|
+
dispose: Disposer;
|
|
11
|
+
};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { Disposer } from '../contracts/ports.ts';
|
|
2
|
+
import { type AccountBalanceBreakdown } from './account-balance-hint.ts';
|
|
2
3
|
/** Last completed display, retained across menu openings for the same account. */
|
|
3
4
|
export interface AccountBalanceCache {
|
|
4
5
|
text?: string;
|
|
5
6
|
description?: string;
|
|
7
|
+
balance?: AccountBalanceBreakdown;
|
|
6
8
|
}
|
|
7
9
|
/** One usage row in the lower-left account menu; polling lives only while open. */
|
|
8
10
|
export declare function mountAccountBalance(menu: HTMLElement, cache?: AccountBalanceCache): Disposer;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Disposer } from '../contracts/ports.ts';
|
|
2
|
+
/** Only append-only visible text gets an entrance; reparsing is already visible. */
|
|
3
|
+
export declare function streamingAppendStart(previous: string, text: string): number | null;
|
|
4
|
+
/** Fade new reply text through native Ranges: never wrap, clone or delay Markdown. */
|
|
5
|
+
export declare function mountConversationStream(document: Document, report: (error: unknown) => void): Disposer;
|
|
@@ -40,8 +40,8 @@ import type { Disposer } from '../contracts/ports.ts';
|
|
|
40
40
|
*
|
|
41
41
|
* Everything written here lands on host nodes as `data-ccd-files-*` markers or
|
|
42
42
|
* as plugin-owned nodes beside them, and the disposer takes all of it back.
|
|
43
|
-
* The module
|
|
44
|
-
*
|
|
43
|
+
* The module shares the right-panel feature lifetime with its stylesheet,
|
|
44
|
+
* so disabling that feature removes every enhancement before its styles.
|
|
45
45
|
*/
|
|
46
46
|
/** The state of the tree, written on the Files root: `hidden` or absent. */
|
|
47
47
|
export declare const TREE_ATTRIBUTE = "data-ccd-files-tree";
|
|
@@ -13,10 +13,9 @@
|
|
|
13
13
|
* and the static web frontend's markdown classes (`_markdown_1ypvv_5`) are
|
|
14
14
|
* identical in both builds, so neither needs an entry here.
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* `app.asar` — the same single-place update `host-dom.ts` documents.
|
|
16
|
+
* Keep the authored build stable and register each verified release below.
|
|
17
|
+
* A new release may rehash every prefix; read its tables from `app.asar`.
|
|
18
|
+
* The latest macOS build is also the preload fallback before the frame mounts.
|
|
20
19
|
*/
|
|
21
20
|
/** One shipped DSH build and the prefixes it uses for the pinned classes. */
|
|
22
21
|
export interface HostBuild {
|
|
@@ -38,6 +37,8 @@ export declare const PINNED_BUILD: HostBuild;
|
|
|
38
37
|
* prefix this plugin authored.
|
|
39
38
|
*/
|
|
40
39
|
export declare const WINDOWS_BUILD: HostBuild;
|
|
40
|
+
/** DSH `0.2.1-rc.3`, macOS commit `be72761e`, read from its shipped app.asar. */
|
|
41
|
+
export declare const MACOS_BUILD: HostBuild;
|
|
41
42
|
/** Every build whose class names this plugin knows how to speak. */
|
|
42
43
|
export declare const HOST_BUILDS: readonly HostBuild[];
|
|
43
44
|
/** How a document's build was decided. */
|
|
@@ -65,7 +65,7 @@ export declare const HOST: Readonly<{
|
|
|
65
65
|
* inline (the resolved width, or `100vw` in full screen). Its
|
|
66
66
|
* `data-sidebar-right-panel` (`push` / `fullscreen`) and
|
|
67
67
|
* `data-sidebar-right-open` are the package's own stable hooks, so the card
|
|
68
|
-
* `
|
|
68
|
+
* `features/right-panel/frame.css` paints on it survives a build whose classes were rehashed; this
|
|
69
69
|
* plugin authors no selector for the panel's hashed class.
|
|
70
70
|
*/
|
|
71
71
|
readonly rightbarPanel: '[data-sidebar-right-panel]';
|
|
@@ -77,7 +77,7 @@ export declare const HOST: Readonly<{
|
|
|
77
77
|
* on, `pane` a dock column that would otherwise paint the canvas over it,
|
|
78
78
|
* `strip` the tab strip (the card's header row), `divider` the hairline
|
|
79
79
|
* between two columns, `empty` a column no tab has claimed. Only
|
|
80
|
-
* `features/
|
|
80
|
+
* `features/right-panel/right-panel.css` reads them.
|
|
81
81
|
*/
|
|
82
82
|
readonly dockSurface: '[data-dockkit-surface]';
|
|
83
83
|
readonly dockPane: '[data-dockkit-pane]';
|
|
@@ -144,6 +144,8 @@ export declare const HOST: Readonly<{
|
|
|
144
144
|
readonly sidebarPanelRow: '._3WPZCG_panelRow';
|
|
145
145
|
readonly sidebarPanelTitle: '._3WPZCG_panelTitle';
|
|
146
146
|
readonly sidebarPanelGlyph: '._3WPZCG_panelGlyph';
|
|
147
|
+
/** SidebarRoot.module.css: the panel list's More card (`PanelMoreMenu`). */
|
|
148
|
+
readonly sidebarMoreMenu: '._3WPZCG_moreMenu';
|
|
147
149
|
readonly sidebarRegionArea: '._3WPZCG_regionArea';
|
|
148
150
|
readonly sidebarFootArea: '._3WPZCG_footArea';
|
|
149
151
|
readonly sidebarSettingsArea: '._3WPZCG_settingsArea';
|
|
@@ -346,6 +348,13 @@ export declare const HOST: Readonly<{
|
|
|
346
348
|
no entry in `host-builds.ts` — the same fact `tokens.css` records for the
|
|
347
349
|
primitive's check mark. */
|
|
348
350
|
readonly menuItemLabel: '._itemLabel_4ub78_190';
|
|
351
|
+
/** Menu.module.css: `MenuItemButton`'s wrap, its button and the separator a
|
|
352
|
+
wrap may lead with — the markup the plugin's own rows in a host menu
|
|
353
|
+
repeat (`features/sidebar-editor/MoreCardRows.tsx`), so the card's
|
|
354
|
+
keyboard walk and every popup rule reach them as host rows. */
|
|
355
|
+
readonly menuItemWrap: '._itemWrap_4ub78_90';
|
|
356
|
+
readonly menuItemButton: '._item_4ub78_90';
|
|
357
|
+
readonly menuSeparator: '._separator_4ub78_80';
|
|
349
358
|
/** Menu.module.css: the trailing mark a *selected* row draws — `Menu` renders
|
|
350
359
|
it only for the row whose id is in `selectedIds`, so its presence is how
|
|
351
360
|
`compat/view-options.ts` reads which option is current. */
|
|
@@ -438,6 +447,14 @@ export type HostAnchors = Readonly<Record<keyof typeof ANCHOR, string>>;
|
|
|
438
447
|
* @param document - the renderer document to speak to.
|
|
439
448
|
*/
|
|
440
449
|
export declare function hostSelectors(document: Document): HostSelectors;
|
|
450
|
+
export interface MenuRowClasses {
|
|
451
|
+
readonly itemWrap: string;
|
|
452
|
+
readonly item: string;
|
|
453
|
+
readonly itemLabel: string;
|
|
454
|
+
readonly separator: string;
|
|
455
|
+
}
|
|
456
|
+
/** The `Menu` primitive's row classes, for rows this plugin renders into a host menu. */
|
|
457
|
+
export declare function menuRowClasses(document: Document): MenuRowClasses;
|
|
441
458
|
/** The anchors of this document's build; see {@link hostSelectors}. */
|
|
442
459
|
export declare function hostAnchors(document: Document): HostAnchors;
|
|
443
460
|
export interface HostProbe {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { SearchPalettePort } from '../contracts/ports.ts';
|
|
3
|
+
/** Read the palette's lists from the host catalogs and drive the host's own navigation. */
|
|
4
|
+
export declare function searchPalettePort(ctx: Context, document: Document, report: (error: unknown) => void): SearchPalettePort;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Disposer } from '../contracts/ports.ts';
|
|
2
|
+
import type { SidebarPanelsPort } from './sidebar-panels.ts';
|
|
3
|
+
/** The panel id this module read off a row's position in the list. */
|
|
4
|
+
export declare const SIDEBAR_PANEL_ATTRIBUTE = "data-ccd-panel";
|
|
5
|
+
/** Marks the list child the Edit sidebar dialog took out of the column. */
|
|
6
|
+
export declare const SIDEBAR_PANEL_HIDDEN_ATTRIBUTE = "data-ccd-panel-hidden";
|
|
7
|
+
/** The ids the Edit sidebar dialog keeps out of the column. */
|
|
8
|
+
export interface HiddenPanels {
|
|
9
|
+
has(id: string): boolean;
|
|
10
|
+
subscribe(listener: () => void): Disposer;
|
|
11
|
+
}
|
|
12
|
+
export interface SidebarPanelRows {
|
|
13
|
+
/** A copy of the glyph a panel's row draws, for the dialog's list. */
|
|
14
|
+
glyph(id: string): Element | null;
|
|
15
|
+
dispose: Disposer;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Name the panel rows by id and keep the hidden ones out of the column.
|
|
19
|
+
*
|
|
20
|
+
* `PanelRow` exposes no id, but `SidebarRoot` renders exactly one row per
|
|
21
|
+
* `sidebar.panellist` entry, in the order the port reads — the host's own pin
|
|
22
|
+
* filter is never written (its only setter reaches the More card's rows, which
|
|
23
|
+
* leave it alone) — so a row's position is its identity. When the counts
|
|
24
|
+
* disagree for a frame (an entry registering while the column has not caught
|
|
25
|
+
* up), the marks are withdrawn rather than guessed: nothing is hidden until the
|
|
26
|
+
* two agree again.
|
|
27
|
+
*
|
|
28
|
+
* A hidden row stays where React rendered it: the mark goes on the list child
|
|
29
|
+
* that holds it, and `sidebar-editor.css` takes that child out of the flow, so
|
|
30
|
+
* the list's gap closes and DSH keeps every node and handler.
|
|
31
|
+
*/
|
|
32
|
+
export declare function mountSidebarPanelRows(document: Document, port: SidebarPanelsPort, hidden: HiddenPanels, report: (error: unknown) => void): SidebarPanelRows;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Disposer } from '../contracts/ports.ts';
|
|
2
|
+
/** Marks the sidebar More card this module places beside its row. */
|
|
3
|
+
export declare const SIDEBAR_MORE_MENU_ATTRIBUTE = "data-ccd-sidebar-more-menu";
|
|
4
|
+
/**
|
|
5
|
+
* Open the sidebar panel list's More card to the right of its row, like the
|
|
6
|
+
* reference's sidebar menu, and shorten its two entry-customization rows.
|
|
7
|
+
*
|
|
8
|
+
* `SidebarRoot` renders the card with the primitive's default bottom side and
|
|
9
|
+
* rewrites `left`/`top` on every frame, so the position is published as two
|
|
10
|
+
* custom properties the stylesheet applies with `!important`; React keeps
|
|
11
|
+
* owning the inline coordinates and the rows keep their host handlers.
|
|
12
|
+
*/
|
|
13
|
+
export declare function mountSidebarMoreMenu(document: Document, report: (error: unknown) => void): Disposer;
|
|
@@ -3,8 +3,16 @@ export interface SidebarNavigationIcons {
|
|
|
3
3
|
readonly newSession: string;
|
|
4
4
|
readonly plugins: string;
|
|
5
5
|
readonly routines: string;
|
|
6
|
+
readonly more: string;
|
|
7
|
+
readonly theme: string;
|
|
6
8
|
}
|
|
7
9
|
export declare const SIDEBAR_NAV_ATTRIBUTE = "data-ccd-nav";
|
|
10
|
+
/** Marks the glyph this plugin's own Theme panel draws, so its row is known by
|
|
11
|
+
what it renders rather than by a label another panel could share. */
|
|
12
|
+
export declare const THEME_PANEL_GLYPH_ATTRIBUTE = "data-ccd-theme-glyph";
|
|
13
|
+
/** The name a panel row shows once this module has renamed it: 插件 reads 自定义
|
|
14
|
+
and 自动化任务 reads 定时任务, every other panel keeps its own label. */
|
|
15
|
+
export declare function panelDisplayName(document: Document, name: string): string;
|
|
8
16
|
/** Rename and decorate the native buttons without replacing React-owned nodes
|
|
9
17
|
* or handlers. Every write is conditional and reversible, including delayed
|
|
10
18
|
* mounts, locale changes, wide/rail rerenders and the native tooltip portals. */
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { ReactElement } from 'react';
|
|
3
|
+
import type { Disposer } from '../contracts/ports.ts';
|
|
4
|
+
/**
|
|
5
|
+
* The sidebar's global panels as `ui-sidebar` lists them.
|
|
6
|
+
*
|
|
7
|
+
* Verified against the installed DSH 0.2.1-rc.3 client bundle: `SidebarRoot`
|
|
8
|
+
* reads `sidebar.panellist` entries' `id`, `order` and `label` (a string or a
|
|
9
|
+
* thunk), sorts them by `order`, and renders one `PanelRow` per entry — the
|
|
10
|
+
* entry's component is only the row's glyph, rendered with `{ size, active }`.
|
|
11
|
+
* The centre column renders the `main` keyed entry whose `key` is the active
|
|
12
|
+
* panel id. `ui-sidebar` is outside the SDK baseline, so the boundary stays
|
|
13
|
+
* structural here, like `settings-section.ts`.
|
|
14
|
+
*/
|
|
15
|
+
export declare const SIDEBAR_PANEL_SLOT = "sidebar.panellist";
|
|
16
|
+
/** Rows of the panel list's More card; `ui-sidebar` shows More while this list has entries. */
|
|
17
|
+
export declare const SIDEBAR_PANEL_ACTIONS_SLOT = "sidebar.panellist.actions";
|
|
18
|
+
export interface SidebarPanel {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
/** The name the row shows, after `sidebar-navigation.ts` renamed it. */
|
|
21
|
+
readonly label: string;
|
|
22
|
+
}
|
|
23
|
+
/** The panel list `ui-sidebar` renders and the one call that opens an entry. */
|
|
24
|
+
export interface SidebarPanelsPort {
|
|
25
|
+
/** Every registered panel in the order the column lists them. */
|
|
26
|
+
panels(): readonly SidebarPanel[];
|
|
27
|
+
subscribe(listener: () => void): Disposer;
|
|
28
|
+
/** The panel the centre column shows, or null on a Session. */
|
|
29
|
+
active(): string | null;
|
|
30
|
+
select(id: string): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* @param ctx - client context carrying the slot and layout services.
|
|
34
|
+
* @param document - the renderer document, whose language names renamed rows.
|
|
35
|
+
*/
|
|
36
|
+
export declare function sidebarPanelsPort(ctx: Context, document: Document): SidebarPanelsPort;
|
|
37
|
+
export interface MainPanelRegistration<P> {
|
|
38
|
+
readonly id: string;
|
|
39
|
+
readonly order: number;
|
|
40
|
+
readonly locale: string;
|
|
41
|
+
readonly label: () => string;
|
|
42
|
+
/** The centre column's page while the panel is active. */
|
|
43
|
+
readonly page: (props: P) => ReactElement | null;
|
|
44
|
+
/** The row's glyph, rendered with the column's `{ size, active }`. */
|
|
45
|
+
readonly glyph: (props: {
|
|
46
|
+
readonly size?: number;
|
|
47
|
+
readonly active?: boolean;
|
|
48
|
+
}) => ReactElement | null;
|
|
49
|
+
}
|
|
50
|
+
/** Register a global panel: its sidebar row and the page it opens. */
|
|
51
|
+
export declare function mountMainPanel<P>(ctx: Context, panel: MainPanelRegistration<P>): Disposer;
|
|
52
|
+
/**
|
|
53
|
+
* Add rows to the panel list's More card. `PanelMoreMenu` renders every
|
|
54
|
+
* `sidebar.panellist.actions` entry, by `order`, inside its `Menu` list with
|
|
55
|
+
* `{ entries, onOpen, onPinnedChange, onDismiss }`; `inject`'s face is merged
|
|
56
|
+
* over those owner props.
|
|
57
|
+
*/
|
|
58
|
+
export declare function mountMoreCardRows<P>(ctx: Context, entry: {
|
|
59
|
+
readonly id: string;
|
|
60
|
+
readonly order: number;
|
|
61
|
+
readonly inject: () => Record<string, unknown>;
|
|
62
|
+
}, rows: (props: P) => ReactElement | null): Disposer;
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import type { Disposer } from '../contracts/ports.ts';
|
|
2
|
-
/** Marks the sidebar column whose
|
|
1
|
+
import type { Disposer, SearchPaletteOpener } from '../contracts/ports.ts';
|
|
2
|
+
/** Marks the sidebar column whose Search row this module placed below New Session. */
|
|
3
3
|
export declare const SIDEBAR_SEARCH_PLACED_ATTRIBUTE = "data-ccd-sidebar-search-placed";
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Give Search its own navigation row below New Session, like the reference's
|
|
6
|
+
* sidebar, and open the search palette from it.
|
|
6
7
|
*
|
|
7
|
-
* The field belongs to `ui-workspace`'s `WorkspaceBrowser`, and React
|
|
8
|
-
* it from the section header whenever the sidebar collapses to its
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* label takes the leading edge and the native View options trigger stays on the
|
|
16
|
-
* trailing edge.
|
|
8
|
+
* The host's field belongs to `ui-workspace`'s `WorkspaceBrowser`, and React
|
|
9
|
+
* removes it from the section header whenever the sidebar collapses to its
|
|
10
|
+
* rail, so the node stays where React put it. While the row is placed,
|
|
11
|
+
* `sidebar.css` takes the field out of sight without making it unfocusable: the
|
|
12
|
+
* host's own `session.search` shortcut (⌘K) still focuses it, and that focus is
|
|
13
|
+
* what this module turns into opening the palette. The row itself is the
|
|
14
|
+
* plugin's own button, inserted after New Session's node; React never addresses
|
|
15
|
+
* it, so a re-render only needs it put back.
|
|
17
16
|
*/
|
|
18
|
-
export declare function mountSidebarSearch(document: Document, report: (error: unknown) => void): Disposer;
|
|
17
|
+
export declare function mountSidebarSearch(document: Document, icon: string, palette: SearchPaletteOpener, report: (error: unknown) => void): Disposer;
|
|
@@ -17,7 +17,8 @@ export declare function openFolderLabel(text: string, zh: boolean): string | nul
|
|
|
17
17
|
* commit that mounts it and never shows the host's glyph first.
|
|
18
18
|
*
|
|
19
19
|
* @param document - renderer document carrying the hero chip and the portal.
|
|
20
|
-
* @param port - Workspace order and new-worktree choices
|
|
20
|
+
* @param port - Workspace order and new-worktree choices (the toggle itself is
|
|
21
|
+
* `mountWorktreeChip`, beside the folder chip).
|
|
21
22
|
* @param report - sink for observer failures; the native label stays untouched.
|
|
22
23
|
* @returns disposer that disconnects every observer and restores each label.
|
|
23
24
|
*/
|
|
@@ -26,7 +26,17 @@ export declare class WorktreeChoices implements WorktreePickerPort {
|
|
|
26
26
|
subscribe(listener: () => void): Disposer;
|
|
27
27
|
prepare(session: string, create: (workspace: string, from?: string) => Promise<WorktreeResult>): Promise<void>;
|
|
28
28
|
}
|
|
29
|
-
/**
|
|
30
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Claude's worktree toggle beside the folder chip: a pressed chip, not a menu
|
|
31
|
+
* row. It is shown only for a new session whose folder is a Git repository,
|
|
32
|
+
* and the optional runtime is enabled. Recheck while visible and on returning
|
|
33
|
+
* to the composer so plugin enable/disable does not leave a stale button.
|
|
34
|
+
*
|
|
35
|
+
* @param document - renderer document carrying the hero workspace row.
|
|
36
|
+
* @param port - per-session worktree choices.
|
|
37
|
+
* @param workspaceOf - the Workspace a session belongs to.
|
|
38
|
+
* @param report - sink for observer failures.
|
|
39
|
+
*/
|
|
40
|
+
export declare function mountWorktreeChip(document: Document, port: WorktreePickerPort, workspaceOf: (session: string) => string | undefined, report: (error: unknown) => void): Disposer;
|
|
31
41
|
/** Request retries reuse the Host's per-session result, including after a lost response. */
|
|
32
42
|
export declare function createSessionWorktree(session: string, workspace: string, from?: string): Promise<WorktreeResult>;
|
|
@@ -296,6 +296,108 @@ export interface ContextPanelPort {
|
|
|
296
296
|
/** Flip the panel between its collapsed and expanded states. */
|
|
297
297
|
toggleExpanded(): void;
|
|
298
298
|
}
|
|
299
|
+
/** One Session as the search palette lists it. */
|
|
300
|
+
export interface PaletteSession {
|
|
301
|
+
readonly id: string;
|
|
302
|
+
readonly title: string;
|
|
303
|
+
/** Title of the Workspace the Session is accounted to; null when ungrouped. */
|
|
304
|
+
readonly workspace: string | null;
|
|
305
|
+
/** Durable activity time, milliseconds since the epoch. */
|
|
306
|
+
readonly updatedAt: number;
|
|
307
|
+
readonly running: boolean;
|
|
308
|
+
readonly archived: boolean;
|
|
309
|
+
readonly pinned: boolean;
|
|
310
|
+
}
|
|
311
|
+
/** One Workspace as the search palette lists it. */
|
|
312
|
+
export interface PaletteProject {
|
|
313
|
+
readonly id: string;
|
|
314
|
+
readonly title: string;
|
|
315
|
+
readonly path: string;
|
|
316
|
+
/** Sessions accounted to it, archived ones included. */
|
|
317
|
+
readonly sessions: number;
|
|
318
|
+
}
|
|
319
|
+
/** A schedule's stored rule, reduced to what its label needs. */
|
|
320
|
+
export type PaletteScheduleRule = {
|
|
321
|
+
readonly kind: 'once';
|
|
322
|
+
readonly at: string;
|
|
323
|
+
} | {
|
|
324
|
+
readonly kind: 'every';
|
|
325
|
+
readonly seconds: number;
|
|
326
|
+
} | {
|
|
327
|
+
readonly kind: 'daily';
|
|
328
|
+
readonly time: string;
|
|
329
|
+
} | {
|
|
330
|
+
readonly kind: 'weekly';
|
|
331
|
+
readonly time: string;
|
|
332
|
+
readonly weekdays: readonly number[];
|
|
333
|
+
} | {
|
|
334
|
+
readonly kind: 'cron';
|
|
335
|
+
readonly expression: string;
|
|
336
|
+
};
|
|
337
|
+
/** One scheduled task from the host catalog. */
|
|
338
|
+
export interface PaletteSchedule {
|
|
339
|
+
readonly id: string;
|
|
340
|
+
readonly sessionId: string;
|
|
341
|
+
readonly title: string;
|
|
342
|
+
readonly prompt: string;
|
|
343
|
+
readonly rule: PaletteScheduleRule;
|
|
344
|
+
readonly active: boolean;
|
|
345
|
+
/** Last durably delivered run, milliseconds since the epoch; null before the first. */
|
|
346
|
+
readonly lastRunAt: number | null;
|
|
347
|
+
}
|
|
348
|
+
/** Everything the palette lists, as one immutable value. */
|
|
349
|
+
export interface SearchPaletteSnapshot {
|
|
350
|
+
/** Listed Sessions: no provisional blanks and no subagent children. */
|
|
351
|
+
readonly sessions: readonly PaletteSession[];
|
|
352
|
+
/** Workspaces in the host's own order. */
|
|
353
|
+
readonly projects: readonly PaletteProject[];
|
|
354
|
+
/** Null on a build without the schedule interface, or while it cannot be read. */
|
|
355
|
+
readonly schedules: readonly PaletteSchedule[] | null;
|
|
356
|
+
}
|
|
357
|
+
/** Run count read from a task's delivery history; `more` when the page was full. */
|
|
358
|
+
export interface PaletteScheduleRuns {
|
|
359
|
+
readonly count: number;
|
|
360
|
+
readonly more: boolean;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* The host data and navigation the search palette is drawn from.
|
|
364
|
+
*
|
|
365
|
+
* Every list is read from the host's own catalogs (`sessions.list`,
|
|
366
|
+
* `workspaces.list`, `schedule/catalog()`) and every action goes through the
|
|
367
|
+
* host's own navigation or mutation, so the palette keeps no copy of state.
|
|
368
|
+
*/
|
|
369
|
+
export interface SearchPalettePort {
|
|
370
|
+
/** The current lists; the object identity changes only when a list does. */
|
|
371
|
+
getSnapshot(): SearchPaletteSnapshot;
|
|
372
|
+
subscribe(listener: () => void): Disposer;
|
|
373
|
+
/** Re-read the schedule catalog; the palette asks on every open. */
|
|
374
|
+
refreshSchedules(): void;
|
|
375
|
+
scheduleRuns(id: string): Promise<PaletteScheduleRuns>;
|
|
376
|
+
/** The host's message-content search; at most its own result bound. */
|
|
377
|
+
searchContent(query: string, signal: AbortSignal): Promise<readonly {
|
|
378
|
+
readonly sessionId: string;
|
|
379
|
+
readonly snippet: string;
|
|
380
|
+
}[]>;
|
|
381
|
+
openSession(id: string): void;
|
|
382
|
+
/** Open the New Session page, in a Workspace and with a draft when given. */
|
|
383
|
+
startSession(options?: {
|
|
384
|
+
readonly workspaceId?: string;
|
|
385
|
+
readonly prompt?: string;
|
|
386
|
+
}): void;
|
|
387
|
+
/** Show the Scheduled tasks page and the task's own detail. */
|
|
388
|
+
openSchedule(id: string): void;
|
|
389
|
+
setPinned(id: string, pinned: boolean): Promise<void>;
|
|
390
|
+
setArchived(id: string, archived: boolean): Promise<void>;
|
|
391
|
+
/** Fork a Session and open the child. */
|
|
392
|
+
fork(id: string): Promise<void>;
|
|
393
|
+
copy(text: string): Promise<void>;
|
|
394
|
+
}
|
|
395
|
+
/** Opens the search palette; the sidebar row mirrors its open state. */
|
|
396
|
+
export interface SearchPaletteOpener {
|
|
397
|
+
open(): void;
|
|
398
|
+
isOpen(): boolean;
|
|
399
|
+
subscribe(listener: () => void): Disposer;
|
|
400
|
+
}
|
|
299
401
|
/** Actual SDK types, never a second definition of DSH component props. */
|
|
300
402
|
export interface HostServices {
|
|
301
403
|
readonly slots: Context['slots'];
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
export type ClaudeFrame = readonly [body: string, shade: string, eyes: string, laptop: string];
|
|
7
7
|
export declare const CLAUDE_GROUND_Y = 23.5;
|
|
8
8
|
export declare const CLAUDE_IDLE: ClaudeFrame;
|
|
9
|
-
/**
|
|
10
|
-
*
|
|
9
|
+
/** Reuse clean silhouettes for the recorded sequence; typing uses a steady
|
|
10
|
+
* far / passing / near cadence instead of changing the hands' contours. */
|
|
11
11
|
export declare const CLAUDE_FRAMES: readonly ClaudeFrame[];
|
|
12
12
|
export declare const CLAUDE_TRACK: readonly number[];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { FeatureEnvironment } from '../../contracts/feature.ts';
|
|
3
|
+
import type { CleanupScope } from '../../core/cleanup.ts';
|
|
4
|
+
/** Styles, injected controls and pane layout share the right-sidebar switch. */
|
|
5
|
+
export declare function mountRightPanel(ctx: Context, environment: FeatureEnvironment, scope: CleanupScope): void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import type { SearchPaletteOpener, SearchPalettePort } from '../../contracts/ports.ts';
|
|
3
|
+
/** The palette's open state, shared with the sidebar row that opens it. */
|
|
4
|
+
export interface PaletteState extends SearchPaletteOpener {
|
|
5
|
+
close(): void;
|
|
6
|
+
}
|
|
7
|
+
interface Props {
|
|
8
|
+
readonly state: PaletteState;
|
|
9
|
+
readonly port: SearchPalettePort;
|
|
10
|
+
readonly report: (error: unknown) => void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The search palette: a modal card opened from the sidebar's Search row or ⌘K.
|
|
14
|
+
*
|
|
15
|
+
* It is drawn after the reference — a borderless field with a close button, a
|
|
16
|
+
* row of type tabs, sectioned results with the current row's `…` and ↵, and a
|
|
17
|
+
* footer of key hints — over lists read from the host's own catalogs. The
|
|
18
|
+
* card is a native modal `<dialog>`, so focus, the top layer and Esc are the
|
|
19
|
+
* browser's; the body is mounted per opening, so each opening starts from 全部
|
|
20
|
+
* with an empty field.
|
|
21
|
+
*/
|
|
22
|
+
export declare function SearchPalette({ state, port, report }: Props): ReactElement;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { PaletteProject, PaletteSchedule, PaletteScheduleRule, PaletteScheduleRuns, PaletteSession, SearchPaletteSnapshot } from '../../contracts/ports.ts';
|
|
2
|
+
/** The palette's type filter; `all` mixes every list. */
|
|
3
|
+
export type PaletteTab = 'all' | 'session' | 'project' | 'schedule';
|
|
4
|
+
/** The first matched run of a label, as UTF-16 offsets. */
|
|
5
|
+
export type MatchRange = readonly [start: number, end: number] | null;
|
|
6
|
+
export type PaletteEntry = {
|
|
7
|
+
readonly kind: 'session';
|
|
8
|
+
readonly key: string;
|
|
9
|
+
readonly session: PaletteSession;
|
|
10
|
+
readonly match: MatchRange;
|
|
11
|
+
readonly snippet: string | null;
|
|
12
|
+
} | {
|
|
13
|
+
readonly kind: 'project';
|
|
14
|
+
readonly key: string;
|
|
15
|
+
readonly project: PaletteProject;
|
|
16
|
+
readonly match: MatchRange;
|
|
17
|
+
} | {
|
|
18
|
+
readonly kind: 'schedule';
|
|
19
|
+
readonly key: string;
|
|
20
|
+
readonly schedule: PaletteSchedule;
|
|
21
|
+
readonly match: MatchRange;
|
|
22
|
+
} | {
|
|
23
|
+
readonly kind: 'action';
|
|
24
|
+
readonly key: string;
|
|
25
|
+
readonly prompt: string;
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: 'filter';
|
|
28
|
+
readonly key: string;
|
|
29
|
+
readonly tab: PaletteTab;
|
|
30
|
+
};
|
|
31
|
+
export interface PaletteSection {
|
|
32
|
+
readonly id: string;
|
|
33
|
+
readonly title: string;
|
|
34
|
+
readonly entries: readonly PaletteEntry[];
|
|
35
|
+
}
|
|
36
|
+
/** One row of an entry's `…` menu; `primary` is what Enter does on the row. */
|
|
37
|
+
export interface PaletteAction {
|
|
38
|
+
readonly id: 'open' | 'pin' | 'unpin' | 'fork' | 'archive' | 'unarchive' | 'new-session' | 'copy-path' | 'open-session';
|
|
39
|
+
readonly label: string;
|
|
40
|
+
readonly primary?: boolean;
|
|
41
|
+
}
|
|
42
|
+
export interface PaletteCopy {
|
|
43
|
+
readonly placeholder: string;
|
|
44
|
+
readonly close: string;
|
|
45
|
+
readonly tabs: Readonly<Record<PaletteTab, string>>;
|
|
46
|
+
readonly recent: string;
|
|
47
|
+
readonly actions: string;
|
|
48
|
+
readonly filters: string;
|
|
49
|
+
readonly newSession: string;
|
|
50
|
+
readonly empty: string;
|
|
51
|
+
readonly archived: string;
|
|
52
|
+
readonly running: string;
|
|
53
|
+
readonly ended: string;
|
|
54
|
+
readonly more: string;
|
|
55
|
+
readonly hints: {
|
|
56
|
+
readonly close: string;
|
|
57
|
+
readonly tabs: string;
|
|
58
|
+
readonly filter: string;
|
|
59
|
+
readonly actions: string;
|
|
60
|
+
readonly compose: string;
|
|
61
|
+
};
|
|
62
|
+
readonly menu: Readonly<Record<PaletteAction['id'], string>>;
|
|
63
|
+
readonly runs: (count: number, more: boolean) => string;
|
|
64
|
+
readonly sessionCount: (count: number) => string;
|
|
65
|
+
readonly daily: string;
|
|
66
|
+
readonly weekdays: string;
|
|
67
|
+
readonly weekday: readonly string[];
|
|
68
|
+
readonly weeklyPrefix: string;
|
|
69
|
+
readonly weekdaySeparator: string;
|
|
70
|
+
readonly every: (amount: number, unit: 'hour' | 'minute' | 'second') => string;
|
|
71
|
+
readonly date: (month: number, day: number, year: number | null) => string;
|
|
72
|
+
readonly failed: (message: string) => string;
|
|
73
|
+
}
|
|
74
|
+
/** The palette's own words, in the document's language. */
|
|
75
|
+
export declare function paletteCopy(language: string): PaletteCopy;
|
|
76
|
+
/** The repeat rule as the reference's title suffix: 每天 9:51 / Daily 9:51. */
|
|
77
|
+
export declare function scheduleRuleLabel(rule: PaletteScheduleRule, copy: PaletteCopy, now?: Date): string;
|
|
78
|
+
/** What a schedule row reads: the task name, then its repeat rule. */
|
|
79
|
+
export declare function scheduleLabel(schedule: PaletteSchedule, copy: PaletteCopy, now?: Date): string;
|
|
80
|
+
/** The right-hand reading of a schedule row. */
|
|
81
|
+
export declare function scheduleMeta(schedule: PaletteSchedule, runs: PaletteScheduleRuns | undefined, copy: PaletteCopy): string;
|
|
82
|
+
/** Case-insensitive first occurrence, or null; an empty query matches nothing. */
|
|
83
|
+
export declare function matchRange(text: string, query: string): MatchRange;
|
|
84
|
+
export interface PaletteQuery {
|
|
85
|
+
/** The field's raw text; a leading `/` asks for the filter list. */
|
|
86
|
+
readonly query: string;
|
|
87
|
+
readonly tab: PaletteTab;
|
|
88
|
+
/** Content hits from the host search for this query, by Session id. */
|
|
89
|
+
readonly content?: ReadonlyMap<string, string> | undefined;
|
|
90
|
+
readonly now?: Date;
|
|
91
|
+
}
|
|
92
|
+
/** Which tabs this build can fill. */
|
|
93
|
+
export declare function paletteTabs(snapshot: SearchPaletteSnapshot): readonly PaletteTab[];
|
|
94
|
+
/** Whether the field's text asks for the filter list rather than a search. */
|
|
95
|
+
export declare function isFilterQuery(query: string): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* The palette's sections for one query and tab.
|
|
98
|
+
*
|
|
99
|
+
* Without a query, 全部 shows the reference's 最近使用 (Sessions and tasks by
|
|
100
|
+
* their last activity) above its 操作, and each type tab lists its own rows.
|
|
101
|
+
* With a query, rows are found by title (a project also by path, a task also
|
|
102
|
+
* by its prompt), ranked prefix → word start → anywhere, then by recency;
|
|
103
|
+
* Sessions the host's content search found are appended with their snippet.
|
|
104
|
+
*/
|
|
105
|
+
export declare function paletteSections(snapshot: SearchPaletteSnapshot, input: PaletteQuery, copy: PaletteCopy): PaletteSection[];
|
|
106
|
+
/** An entry's `…` menu, primary action first; empty for rows without one. */
|
|
107
|
+
export declare function entryActions(entry: PaletteEntry, copy: PaletteCopy): readonly PaletteAction[];
|
|
108
|
+
/** Relative activity time for a Session row: 3 小时前 / 3 hours ago. */
|
|
109
|
+
export declare function relativeTime(at: number, language: string, now?: number): string;
|