dsh-claude-desktop-theme 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -54
- package/lib/client.js +9392 -2579
- package/lib/index.js +387 -20
- package/lib/types/client/compat/account-menu.d.ts +4 -4
- package/lib/types/client/compat/account-more.d.ts +3 -0
- package/lib/types/client/compat/account-theme.d.ts +3 -0
- package/lib/types/client/compat/adapter.d.ts +22 -1
- package/lib/types/client/compat/browser-header.d.ts +57 -0
- package/lib/types/client/compat/browser-menu.d.ts +16 -0
- package/lib/types/client/compat/composer-menus.d.ts +6 -3
- package/lib/types/client/compat/context-panel.d.ts +47 -0
- package/lib/types/client/compat/empty-groups.d.ts +46 -0
- package/lib/types/client/compat/files-pane.d.ts +78 -0
- package/lib/types/client/compat/header-menu-actions.d.ts +14 -0
- package/lib/types/client/compat/header-menus.d.ts +4 -0
- package/lib/types/client/compat/host-dom.d.ts +180 -0
- package/lib/types/client/compat/pane-chrome.d.ts +29 -0
- package/lib/types/client/compat/pane-icons.d.ts +23 -0
- package/lib/types/client/compat/pane-tiles.d.ts +37 -0
- package/lib/types/client/compat/permission-menu.d.ts +88 -0
- package/lib/types/client/compat/relative-file-path.d.ts +2 -0
- package/lib/types/client/compat/right-panes.d.ts +16 -0
- package/lib/types/client/compat/scroll-pill.d.ts +70 -0
- package/lib/types/client/compat/sidebar-navigation.d.ts +11 -0
- package/lib/types/client/compat/stats-values.d.ts +18 -1
- package/lib/types/client/compat/view-options.d.ts +58 -0
- package/lib/types/client/compat/view-switch.d.ts +46 -5
- package/lib/types/client/contracts/ports.d.ts +176 -1
- package/lib/types/client/features/context-panel/ContextPanel.d.ts +12 -0
- package/lib/types/client/features/context-panel/mount.d.ts +20 -0
- package/lib/types/client/features/conversation/index.d.ts +5 -3
- package/lib/types/client/features/conversation/view-switch-icons.d.ts +13 -0
- package/lib/types/client/features/settings/locales.d.ts +7 -0
- package/lib/types/client/features/shell/index.d.ts +9 -3
- package/lib/types/client/features/sidebar/index.d.ts +1 -1
- package/lib/types/client/features/sidebar/navigation-icons.d.ts +6 -0
- package/lib/types/client/features/statistics/books.d.ts +1 -2
- package/lib/types/client/features/statistics/format.d.ts +4 -4
- package/lib/types/client/features/view-options/ViewOptionsCard.d.ts +30 -0
- package/lib/types/client/features/view-options/mount.d.ts +25 -0
- package/lib/types/client/theme/mount.d.ts +2 -2
- package/lib/types/client/theme/palette.d.ts +1 -1
- package/lib/types/host/context/compaction.d.ts +26 -0
- package/lib/types/host/context/pricing.d.ts +99 -0
- package/lib/types/host/context/service.d.ts +24 -0
- package/lib/types/host/context/unit.d.ts +136 -0
- package/lib/types/host/index.d.ts +18 -0
- package/lib/types/shared/config.d.ts +26 -1
- package/lib/types/shared/context.d.ts +243 -0
- package/package.json +6 -3
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import type { ImplementedFeature } from '../../contracts/feature.ts';
|
|
2
2
|
/**
|
|
3
3
|
* Window frame and column geometry: flat surfaces, the sidebar column and its
|
|
4
|
-
* divider. The three tracks stay entirely
|
|
5
|
-
* sidebar with the handle moves the divider
|
|
6
|
-
* paints the columns.
|
|
4
|
+
* divider, and the right panel's floating card. The three tracks stay entirely
|
|
5
|
+
* `ui-layout`'s solve, so resizing the sidebar with the handle moves the divider
|
|
6
|
+
* the pointer is on; the plugin only paints the columns.
|
|
7
|
+
*
|
|
8
|
+
* The right panel is a column's occupant rather than a track, so its card is
|
|
9
|
+
* two sheets: `shell.css` insets the panel's box and paints the surface, and
|
|
10
|
+
* `right-panel.css` dresses what the panel draws inside it — the file tree's
|
|
11
|
+
* rows included, which belong to no feature of this plugin's own. Both mount
|
|
12
|
+
* with the frame, because neither has a switch of its own to lose.
|
|
7
13
|
*/
|
|
8
14
|
export declare const shellFeature: ImplementedFeature;
|
|
@@ -3,7 +3,7 @@ import type { ImplementedFeature } from '../../contracts/feature.ts';
|
|
|
3
3
|
* Sidebar presentation: compact navigation rows, flat project groups and a
|
|
4
4
|
* calmer foot. Every entry DSH registers — New Session, the global panel list,
|
|
5
5
|
* the workspace browser and Settings — stays exactly where the host put it; the
|
|
6
|
-
* account menu
|
|
6
|
+
* account menu gains a More submenu that forwards the host feedback action.
|
|
7
7
|
*
|
|
8
8
|
* The one list policy this module owns is the provisional New Session row: DSH
|
|
9
9
|
* creates the Session as soon as New Session is used, and the host marks that
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Approved Claude sidebar SVG artwork, bundled as trusted static markup. */
|
|
2
|
+
export declare const SIDEBAR_NAVIGATION_ICONS: Readonly<{
|
|
3
|
+
newSession: "<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"claude-sidebar-icon\" data-icon=\"new\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle class=\"icon-disc\" cx=\"12\" cy=\"12\" r=\"12\" fill=\"currentColor\" fill-opacity=\"0.09\"/>\n <path d=\"M12 7V17M7 12H17\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\"/>\n</svg>";
|
|
4
|
+
plugins: "<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"claude-sidebar-icon\" data-icon=\"customize\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <g class=\"customize-case\" stroke=\"currentColor\" stroke-width=\"1.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M8 7V5.2C8 4.54 8.54 4 9.2 4H14.8C15.46 4 16 4.54 16 5.2V7\"/>\n <rect x=\"3\" y=\"7\" width=\"18\" height=\"12.5\" rx=\"1.5\"/>\n <path d=\"M3 13.5H7M9.5 13.5H14.5M17 13.5H21\"/>\n </g>\n</svg>";
|
|
5
|
+
routines: "<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"claude-sidebar-icon\" data-icon=\"routines\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <g stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"9\"/>\n <path class=\"routine-long-hand\" d=\"M12 12V7.4\"/>\n <path d=\"M12 12L14.8 13.75\"/>\n </g>\n</svg>";
|
|
6
|
+
}>;
|
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
* ```
|
|
14
14
|
*
|
|
15
15
|
* Only the sentence is copied; nothing is fetched and no book text is
|
|
16
|
-
* involved.
|
|
17
|
-
* including its typographic apostrophe and multiplication sign.
|
|
16
|
+
* involved. Titles and sentences are localized into Simplified Chinese.
|
|
18
17
|
*/
|
|
19
18
|
/** One comparable book: the title as printed, and the tokens it would take. */
|
|
20
19
|
export interface Book {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Number and date formatting for the statistics card.
|
|
3
3
|
*
|
|
4
|
-
* The card
|
|
5
|
-
*
|
|
4
|
+
* The card uses Simplified Chinese dates and a 24-hour clock. Compact token
|
|
5
|
+
* units stay unchanged so the metrics and chart labels fit the card.
|
|
6
6
|
* They live in their own module because both the data layer (`view.ts`) and the
|
|
7
7
|
* DOM layer (`card.ts`) need them, and neither should import the other.
|
|
8
8
|
*/
|
|
@@ -21,14 +21,14 @@ export declare function formatCount(value: number): string;
|
|
|
21
21
|
*/
|
|
22
22
|
export declare function formatTokens(value: number): string;
|
|
23
23
|
/**
|
|
24
|
-
* One hour of the day
|
|
24
|
+
* One hour of the day in the 24-hour clock (`11:00`).
|
|
25
25
|
*
|
|
26
26
|
* @param hour - local hour, 0-23.
|
|
27
27
|
* @returns the label.
|
|
28
28
|
*/
|
|
29
29
|
export declare function formatHour(hour: number): string;
|
|
30
30
|
/**
|
|
31
|
-
* One `YYYY-MM-DD` key as
|
|
31
|
+
* One `YYYY-MM-DD` key as a Chinese chart date (`9月30日`).
|
|
32
32
|
*
|
|
33
33
|
* @param date - local day key.
|
|
34
34
|
* @returns the short label.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import type { ViewOptionsPort } from '../../contracts/ports.ts';
|
|
3
|
+
export interface ViewOptionsCardProps {
|
|
4
|
+
readonly port: ViewOptionsPort;
|
|
5
|
+
/** `view.showEmptyGroups`: whether empty Workspaces are kept on screen. */
|
|
6
|
+
readonly showEmptyGroups: boolean;
|
|
7
|
+
/** Write the switch back through the settings transport. */
|
|
8
|
+
readonly setShowEmptyGroups: (value: boolean) => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The sidebar's view-options card, drawn in this plugin's own words and geometry.
|
|
12
|
+
*
|
|
13
|
+
* DSH's own menu is a flat list of eight options under three grey headings. The
|
|
14
|
+
* reference draws the same settings as *value rows* — the dimension on the left,
|
|
15
|
+
* the current choice on the right, a disclosure mark at the end — with the
|
|
16
|
+
* options one level down in a card of their own, and the switch and the action
|
|
17
|
+
* that belong to the family at the bottom. So this card is that shape, and the
|
|
18
|
+
* host's menu is only ever read (`port.read`) and clicked (`port.choose`): the
|
|
19
|
+
* three values are the host's, its rows are what writes them, and the words of
|
|
20
|
+
* two of the three rows are the host's own — the card borrows the labels it read
|
|
21
|
+
* out of the host's card and renames only the archived-visibility triple, which
|
|
22
|
+
* is the one set the reference names differently (活跃 / 已归档 / 全部).
|
|
23
|
+
*
|
|
24
|
+
* Only `显示空分组` is this plugin's own state: it writes
|
|
25
|
+
* `view.showEmptyGroups` through the settings transport, and a write re-mounts
|
|
26
|
+
* the plugin, so the card closes behind it. `清除筛选` puts the filter rows back
|
|
27
|
+
* to their defaults and exists only while one of them is off its default, which
|
|
28
|
+
* is what the reference does with `Clear filters`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function ViewOptionsCard({ port, showEmptyGroups, setShowEmptyGroups, }: ViewOptionsCardProps): ReactElement | null;
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
import type { ViewOptionsSettingsPort } from '../../contracts/ports.ts';
|
|
5
|
+
/**
|
|
6
|
+
* Put the sidebar's view-options card in the frame-wide overlay.
|
|
7
|
+
*
|
|
8
|
+
* The card is this plugin's own surface, so it is registered like one: a React
|
|
9
|
+
* entry in `shell.overlay`, holding the driver that watches the host's trigger
|
|
10
|
+
* and drives the host's own menu (`compat/view-options.ts`). The one value the
|
|
11
|
+
* card writes is `view.showEmptyGroups`, and it goes through the settings
|
|
12
|
+
* transport the same way the configuration page writes its fields — a write
|
|
13
|
+
* re-mounts the plugin, which is why the card closes behind the switch.
|
|
14
|
+
*
|
|
15
|
+
* Nothing here fails the interface if the trigger is missing: the driver reports
|
|
16
|
+
* a card it cannot read and hands the click back to DSH, whose own menu opens.
|
|
17
|
+
*
|
|
18
|
+
* @param ctx - client root context carrying the slot service.
|
|
19
|
+
* @param environment - configuration, ports and logging for this activation.
|
|
20
|
+
* @param cleanup - scope owning the styles, the driver and the registration.
|
|
21
|
+
*/
|
|
22
|
+
export declare function mountViewOptions(ctx: Context, environment: FeatureEnvironment, cleanup: CleanupScope): {
|
|
23
|
+
settings: ViewOptionsSettingsPort;
|
|
24
|
+
showAllSessions(): void;
|
|
25
|
+
};
|
|
@@ -3,8 +3,8 @@ import type { CleanupScope } from '../core/cleanup.ts';
|
|
|
3
3
|
/**
|
|
4
4
|
* Plugin-scoped presentation base: the root activation marker, the design
|
|
5
5
|
* variables, the shared Composer geometry two features depend on (siblings must
|
|
6
|
-
* not import each other), the host popup chrome (DESIGN.md §6.7)
|
|
7
|
-
* semantic token overrides.
|
|
6
|
+
* not import each other), the host popup chrome (DESIGN.md §6.7), the ink the
|
|
7
|
+
* window's scrollbars are painted in and the semantic token overrides.
|
|
8
8
|
*
|
|
9
9
|
* The override layer is recomputed on every mount, so a configuration change
|
|
10
10
|
* releases the previous layer through the same scope that owns the stylesheets
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The autocompaction policy this deployment actually runs.
|
|
3
|
+
*
|
|
4
|
+
* The panel's last row says how much of the window the compaction policy is
|
|
5
|
+
* holding back, and that number belongs to another plugin's configuration. DSH
|
|
6
|
+
* publishes no read face for it, so the loader's own entry tree is the source:
|
|
7
|
+
* an entry that is enabled *and* declares the policy's own fields
|
|
8
|
+
* (`thresholdRatio` / `headroomTokens`) is the backend that will compact this
|
|
9
|
+
* session, and an enabled `compaction-basic` with an empty config is that
|
|
10
|
+
* backend running on its defaults.
|
|
11
|
+
*
|
|
12
|
+
* A deployment with no such entry — which is this plugin's own machine, where
|
|
13
|
+
* `compaction-basic` is `disabled: true` — yields null, and the panel leaves
|
|
14
|
+
* the row out rather than drawing a threshold nobody enforces.
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
18
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
19
|
+
import type { CompactionPolicy } from './unit.ts';
|
|
20
|
+
/**
|
|
21
|
+
* The policy that will compact a session on this deployment.
|
|
22
|
+
*
|
|
23
|
+
* @param ctx - host plugin context carrying the loader.
|
|
24
|
+
* @returns the policy, or null when no enabled backend declares one.
|
|
25
|
+
*/
|
|
26
|
+
export declare function readCompactionPolicy(ctx: Context): CompactionPolicy | null;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/** One content block, as far as pricing reads it. */
|
|
2
|
+
export interface PricedBlock {
|
|
3
|
+
readonly type?: string;
|
|
4
|
+
readonly text?: string;
|
|
5
|
+
readonly name?: string;
|
|
6
|
+
readonly arguments?: string;
|
|
7
|
+
/** Every other field the block carries; pricing only ever serializes them. */
|
|
8
|
+
readonly [field: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
/** One model-visible message, as far as pricing reads it. */
|
|
11
|
+
export interface PricedMessage {
|
|
12
|
+
/** Absent for a `user/message` payload, which *is* the message. */
|
|
13
|
+
readonly role?: string;
|
|
14
|
+
readonly content: readonly PricedBlock[];
|
|
15
|
+
}
|
|
16
|
+
/** One tool schema, as far as pricing reads it. */
|
|
17
|
+
export interface PricedTool {
|
|
18
|
+
readonly name: string;
|
|
19
|
+
}
|
|
20
|
+
/** The structural slice of one session event this fold reads. */
|
|
21
|
+
export interface PricedEvent {
|
|
22
|
+
readonly type: string;
|
|
23
|
+
readonly seq: number;
|
|
24
|
+
readonly surfaceOp?: 'append' | {
|
|
25
|
+
readonly startSeq: number;
|
|
26
|
+
readonly endSeq: number;
|
|
27
|
+
};
|
|
28
|
+
readonly data?: {
|
|
29
|
+
readonly content?: readonly PricedBlock[];
|
|
30
|
+
readonly message?: PricedMessage;
|
|
31
|
+
readonly source?: {
|
|
32
|
+
readonly kind?: string;
|
|
33
|
+
readonly changes?: readonly {
|
|
34
|
+
readonly action?: string;
|
|
35
|
+
readonly path?: string;
|
|
36
|
+
}[];
|
|
37
|
+
readonly entries?: readonly {
|
|
38
|
+
readonly name?: string;
|
|
39
|
+
readonly description?: string;
|
|
40
|
+
}[];
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Price one content block list.
|
|
46
|
+
*
|
|
47
|
+
* @param blocks - the message's content.
|
|
48
|
+
* @returns heuristic tokens including per-block structural overhead.
|
|
49
|
+
*/
|
|
50
|
+
export declare function priceContent(blocks: readonly PricedBlock[]): number;
|
|
51
|
+
/**
|
|
52
|
+
* Price one model-visible message.
|
|
53
|
+
*
|
|
54
|
+
* A system prompt is serialized as a plain string by every adapter, so the host
|
|
55
|
+
* prices it as text density plus role framing with no per-block overhead; every
|
|
56
|
+
* other role takes the per-block arm.
|
|
57
|
+
*
|
|
58
|
+
* @param message - the derived message, or null when the event produces none.
|
|
59
|
+
* @returns heuristic tokens.
|
|
60
|
+
*/
|
|
61
|
+
export declare function priceMessage(message: PricedMessage | null): number;
|
|
62
|
+
/**
|
|
63
|
+
* The message one surface event projects to, or null when it produces none.
|
|
64
|
+
*
|
|
65
|
+
* @param event - one committed session event.
|
|
66
|
+
* @returns the message to price.
|
|
67
|
+
*/
|
|
68
|
+
export declare function derivedMessage(event: PricedEvent): PricedMessage | null;
|
|
69
|
+
/** Whether an event carries a surface placement and therefore joins the fold. */
|
|
70
|
+
export declare function isSurfaceEvent(event: PricedEvent): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Price one tool schema on its own.
|
|
73
|
+
*
|
|
74
|
+
* The host prices the assembled array whole, so these per-tool numbers never
|
|
75
|
+
* add back up to it; {@link splitTools} is what keeps the two group rows
|
|
76
|
+
* summing to the host's own total.
|
|
77
|
+
*
|
|
78
|
+
* @param tool - one entry of `EpochHeader.tools`.
|
|
79
|
+
* @returns heuristic tokens for that entry alone.
|
|
80
|
+
*/
|
|
81
|
+
export declare function priceTool(tool: unknown): number;
|
|
82
|
+
/**
|
|
83
|
+
* Price the assembled tool array exactly as the host does.
|
|
84
|
+
*
|
|
85
|
+
* @param tools - `EpochHeader.tools`.
|
|
86
|
+
* @returns the array's heuristic price; 0 when there are no tools.
|
|
87
|
+
*/
|
|
88
|
+
export declare function priceTools(tools: readonly PricedTool[] | undefined): number;
|
|
89
|
+
/**
|
|
90
|
+
* Split one token total across weighted entries, preserving the total exactly.
|
|
91
|
+
*
|
|
92
|
+
* The last entry takes whatever rounding left over, so the rows a group draws
|
|
93
|
+
* always add back up to the group's own number.
|
|
94
|
+
*
|
|
95
|
+
* @param total - tokens to distribute.
|
|
96
|
+
* @param weights - one weight per entry; non-positive weights fall back to 1.
|
|
97
|
+
* @returns one token count per entry, summing to `total`.
|
|
98
|
+
*/
|
|
99
|
+
export declare function allocate(total: number, weights: readonly number[]): readonly number[];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mount the context panel's projection unit.
|
|
3
|
+
*
|
|
4
|
+
* The unit is the only thing the host half adds: the browser half reads the
|
|
5
|
+
* host's own `contextPressure` / `contextBreakdown` straight off the session
|
|
6
|
+
* list, so there is no route, no polling and no second state store — one
|
|
7
|
+
* registration on the session-projection seam, riding this plugin's fiber like
|
|
8
|
+
* `stats/unit.ts` does.
|
|
9
|
+
*
|
|
10
|
+
* A plugin's `apply` runs as soon as its own fiber starts, which can be before
|
|
11
|
+
* the projection registry exists: the optional injection below waits for it,
|
|
12
|
+
* and a deployment that mounts no registry simply never gets the panel's
|
|
13
|
+
* per-tool rows — the card falls back to the host's three numbers alone.
|
|
14
|
+
*
|
|
15
|
+
* @module
|
|
16
|
+
*/
|
|
17
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
18
|
+
/**
|
|
19
|
+
* Register the `ccdContext` unit, once the projection registry exists.
|
|
20
|
+
*
|
|
21
|
+
* @param ctx - host plugin context.
|
|
22
|
+
* @param isEnabled - current plugin switch, read at mount time.
|
|
23
|
+
*/
|
|
24
|
+
export declare function mountContextBreakdown(ctx: Context, isEnabled: () => boolean): void;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure `ccdContext` fold over committed session events.
|
|
3
|
+
*
|
|
4
|
+
* The host already publishes `contextBreakdown` — system prompt, tools,
|
|
5
|
+
* conversation — and `contextPressure`. Neither says *which* tool, *which*
|
|
6
|
+
* instruction file or *which* skill holds the tokens, and nothing outside the
|
|
7
|
+
* token meter can answer that from a wire value. So this unit mirrors the
|
|
8
|
+
* meter's own surface fold: it prices every message-producing event with the
|
|
9
|
+
* same heuristic, honours `surfaceOp` replacements exactly as
|
|
10
|
+
* `contextBreakdown` does, and keeps the priced surface so the two classified
|
|
11
|
+
* kinds can be summed at read time.
|
|
12
|
+
*
|
|
13
|
+
* The mirror is exact rather than approximate — against a real 19 MB session
|
|
14
|
+
* log it reproduces the host's persisted `{systemTokens: 1953, toolsTokens:
|
|
15
|
+
* 7492, messageTokens: 93461}` to the token — and `tests/context-pricing.test.ts`
|
|
16
|
+
* pins that. What it deliberately does *not* do is restate the whole
|
|
17
|
+
* breakdown: the system prompt and the conversation are the host's numbers, and
|
|
18
|
+
* this unit only re-derives the two shares that come out of `messageTokens`.
|
|
19
|
+
*
|
|
20
|
+
* @module
|
|
21
|
+
*/
|
|
22
|
+
import type { ProjectionDefinition } from '@deepseek-ai/dsh-session-projection';
|
|
23
|
+
import { CONTEXT_KEY, type ContextBreakdownView, type ContextEntry } from '../../shared/context.ts';
|
|
24
|
+
import { type PricedEvent } from './pricing.ts';
|
|
25
|
+
declare module '@deepseek-ai/dsh-session-projection/types' {
|
|
26
|
+
interface SessionProjectionStateMap {
|
|
27
|
+
ccdContext: ContextState;
|
|
28
|
+
}
|
|
29
|
+
interface SessionProjectionMap {
|
|
30
|
+
ccdContext: ContextBreakdownView;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** The autocompaction policy this deployment runs, as the loader declares it. */
|
|
34
|
+
export interface CompactionPolicy {
|
|
35
|
+
/** `thresholdRatio`; the window share a compaction may fill. */
|
|
36
|
+
readonly ratio: number;
|
|
37
|
+
/** `headroomTokens`; room kept above the summary budget. */
|
|
38
|
+
readonly headroom: number;
|
|
39
|
+
}
|
|
40
|
+
/** Node kinds the fold classifies; everything else is `OTHER`. */
|
|
41
|
+
export declare const KIND_OTHER = 0;
|
|
42
|
+
/** A retained `agent-instructions` message. */
|
|
43
|
+
export declare const KIND_INSTRUCTIONS = 1;
|
|
44
|
+
/** A retained `skill-catalog` message. */
|
|
45
|
+
export declare const KIND_SKILLS = 2;
|
|
46
|
+
/**
|
|
47
|
+
* One retained surface node: `[seq, tokens, kind, entries]`.
|
|
48
|
+
*
|
|
49
|
+
* `entries` is empty for anything but the two classified kinds; for those it is
|
|
50
|
+
* the node's own price already split across the files or skills it names, so
|
|
51
|
+
* summing a kind's entries is summing its nodes.
|
|
52
|
+
*/
|
|
53
|
+
export type ContextNode = readonly [
|
|
54
|
+
seq: number,
|
|
55
|
+
tokens: number,
|
|
56
|
+
kind: number,
|
|
57
|
+
entries: readonly ContextEntry[]
|
|
58
|
+
];
|
|
59
|
+
/** Fold state: plain JSON, one value per session. */
|
|
60
|
+
export interface ContextState {
|
|
61
|
+
/** Every retained surface node, in model-visible order. */
|
|
62
|
+
readonly nodes: readonly ContextNode[];
|
|
63
|
+
/** Per-tool prices from the latest request envelope, largest first. */
|
|
64
|
+
readonly tools: readonly ContextEntry[];
|
|
65
|
+
/** `request/context` capacity, 0 until one is logged. */
|
|
66
|
+
readonly window: number;
|
|
67
|
+
/** The envelope's own output cap, or null when it declares none. */
|
|
68
|
+
readonly reserved: number | null;
|
|
69
|
+
}
|
|
70
|
+
/** Empty state for one session. */
|
|
71
|
+
export declare function initContextState(): ContextState;
|
|
72
|
+
/**
|
|
73
|
+
* One instruction message's price, split across the files it names.
|
|
74
|
+
*
|
|
75
|
+
* The paths come from `source.changes` — the structured record of what that
|
|
76
|
+
* message carries — and the split weights come from each file's own section, so
|
|
77
|
+
* a message carrying two files of very different size does not report them as
|
|
78
|
+
* equal. A path whose section cannot be located takes an even weight.
|
|
79
|
+
*
|
|
80
|
+
* @param event - the retained `agent-instructions` message.
|
|
81
|
+
* @param tokens - the message's own heuristic price.
|
|
82
|
+
* @returns one row per named file, summing to `tokens`.
|
|
83
|
+
*/
|
|
84
|
+
export declare function instructionEntries(event: PricedEvent, tokens: number): readonly ContextEntry[];
|
|
85
|
+
/**
|
|
86
|
+
* One skill catalog's price, split across the entries it lists.
|
|
87
|
+
*
|
|
88
|
+
* The catalog's structured `entries` are the names; their descriptions are the
|
|
89
|
+
* only per-entry size the message carries, so they are what the split weighs.
|
|
90
|
+
*
|
|
91
|
+
* @param event - the retained `skill-catalog` message.
|
|
92
|
+
* @param tokens - the message's own heuristic price.
|
|
93
|
+
* @returns one row per listed skill, summing to `tokens`.
|
|
94
|
+
*/
|
|
95
|
+
export declare function skillEntries(event: PricedEvent, tokens: number): readonly ContextEntry[];
|
|
96
|
+
/**
|
|
97
|
+
* Advance the fold by one committed event.
|
|
98
|
+
*
|
|
99
|
+
* @param state - state covering every earlier event.
|
|
100
|
+
* @param event - the next committed session event.
|
|
101
|
+
* @returns the next state, or the same reference when the event is not ours.
|
|
102
|
+
*/
|
|
103
|
+
export declare function applyContextEvent(state: ContextState, event: PricedEvent): ContextState;
|
|
104
|
+
/**
|
|
105
|
+
* Project one state onto the client-visible value.
|
|
106
|
+
*
|
|
107
|
+
* @param state - current fold state.
|
|
108
|
+
* @param policy - the deployment's autocompaction policy, or null when none runs.
|
|
109
|
+
* @returns the whole current value.
|
|
110
|
+
*/
|
|
111
|
+
export declare function viewContext(state: ContextState, policy: CompactionPolicy | null): ContextBreakdownView;
|
|
112
|
+
/** Read one persisted state row; lenient, because a read must never throw. */
|
|
113
|
+
export declare function readContextState(value: unknown): ContextState;
|
|
114
|
+
/** Read one wire view row, leniently — the schema slot never throws. */
|
|
115
|
+
export declare function readContextView(value: unknown): ContextBreakdownView;
|
|
116
|
+
/**
|
|
117
|
+
* The registry's wire-unit shape: the definition with its optional `wire`
|
|
118
|
+
* field made required, which is the overload a client-visible key registers
|
|
119
|
+
* through.
|
|
120
|
+
*/
|
|
121
|
+
type WireUnit = Omit<ProjectionDefinition<typeof CONTEXT_KEY>, 'wire'> & {
|
|
122
|
+
wire: NonNullable<ProjectionDefinition<typeof CONTEXT_KEY>['wire']>;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Build the unit this plugin registers on `ctx.sessionProjections`.
|
|
126
|
+
*
|
|
127
|
+
* The policy is read through a callback rather than captured once: the unit is
|
|
128
|
+
* registered while the plugin is on, and a settings write that enables or
|
|
129
|
+
* reconfigures compaction lands in the loader's entry tree without remounting
|
|
130
|
+
* this plugin.
|
|
131
|
+
*
|
|
132
|
+
* @param policy - reads the deployment's autocompaction policy, or null.
|
|
133
|
+
* @returns the projection unit.
|
|
134
|
+
*/
|
|
135
|
+
export declare function createContextProjection(policy: () => CompactionPolicy | null): WireUnit;
|
|
136
|
+
export {};
|
|
@@ -24,6 +24,8 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
24
24
|
'tool-calls': z<boolean, boolean, "defined">;
|
|
25
25
|
statistics: z<boolean, boolean, "defined">;
|
|
26
26
|
'composer-pet': z<boolean, boolean, "defined">;
|
|
27
|
+
'composer-stats': z<boolean, boolean, "defined">;
|
|
28
|
+
'context-panel': z<boolean, boolean, "defined">;
|
|
27
29
|
}>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
|
|
28
30
|
shell: z<boolean, boolean, "defined">;
|
|
29
31
|
sidebar: z<boolean, boolean, "defined">;
|
|
@@ -32,6 +34,8 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
32
34
|
'tool-calls': z<boolean, boolean, "defined">;
|
|
33
35
|
statistics: z<boolean, boolean, "defined">;
|
|
34
36
|
'composer-pet': z<boolean, boolean, "defined">;
|
|
37
|
+
'composer-stats': z<boolean, boolean, "defined">;
|
|
38
|
+
'context-panel': z<boolean, boolean, "defined">;
|
|
35
39
|
}>>>, "volatile-defined">;
|
|
36
40
|
appearance: z<NoInfer<Schemastery.ObjectS<NoInfer<{
|
|
37
41
|
canvas: z<string, string, "defined">;
|
|
@@ -49,6 +53,11 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
49
53
|
uiCjk: z<string, string, "defined">;
|
|
50
54
|
code: z<string, string, "defined">;
|
|
51
55
|
}>>>, "volatile-defined">;
|
|
56
|
+
view: z<NoInfer<Schemastery.ObjectS<NoInfer<{
|
|
57
|
+
showEmptyGroups: z<boolean, boolean, "defined">;
|
|
58
|
+
}>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
|
|
59
|
+
showEmptyGroups: z<boolean, boolean, "defined">;
|
|
60
|
+
}>>>, "volatile-defined">;
|
|
52
61
|
}>>, Schemastery.ObjectT<NoInfer<{
|
|
53
62
|
enabled: z<boolean, boolean, "volatile-defined">;
|
|
54
63
|
debug: z<boolean, boolean, "volatile-defined">;
|
|
@@ -60,6 +69,8 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
60
69
|
'tool-calls': z<boolean, boolean, "defined">;
|
|
61
70
|
statistics: z<boolean, boolean, "defined">;
|
|
62
71
|
'composer-pet': z<boolean, boolean, "defined">;
|
|
72
|
+
'composer-stats': z<boolean, boolean, "defined">;
|
|
73
|
+
'context-panel': z<boolean, boolean, "defined">;
|
|
63
74
|
}>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
|
|
64
75
|
shell: z<boolean, boolean, "defined">;
|
|
65
76
|
sidebar: z<boolean, boolean, "defined">;
|
|
@@ -68,6 +79,8 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
68
79
|
'tool-calls': z<boolean, boolean, "defined">;
|
|
69
80
|
statistics: z<boolean, boolean, "defined">;
|
|
70
81
|
'composer-pet': z<boolean, boolean, "defined">;
|
|
82
|
+
'composer-stats': z<boolean, boolean, "defined">;
|
|
83
|
+
'context-panel': z<boolean, boolean, "defined">;
|
|
71
84
|
}>>>, "volatile-defined">;
|
|
72
85
|
appearance: z<NoInfer<Schemastery.ObjectS<NoInfer<{
|
|
73
86
|
canvas: z<string, string, "defined">;
|
|
@@ -85,6 +98,11 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
85
98
|
uiCjk: z<string, string, "defined">;
|
|
86
99
|
code: z<string, string, "defined">;
|
|
87
100
|
}>>>, "volatile-defined">;
|
|
101
|
+
view: z<NoInfer<Schemastery.ObjectS<NoInfer<{
|
|
102
|
+
showEmptyGroups: z<boolean, boolean, "defined">;
|
|
103
|
+
}>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
|
|
104
|
+
showEmptyGroups: z<boolean, boolean, "defined">;
|
|
105
|
+
}>>>, "volatile-defined">;
|
|
88
106
|
}>>, "plain">;
|
|
89
107
|
/**
|
|
90
108
|
* Host half: the configuration surface the interface reads, plus the read-only
|
|
@@ -1,20 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The interface modules a configuration switch turns on.
|
|
3
|
+
*
|
|
4
|
+
* `composer-stats` is the one entry that mounts nothing of its own: it is the
|
|
5
|
+
* Composer status bar's statistics readouts — `compat/stats-values.ts` plus the
|
|
6
|
+
* Composer sheet — and it is off by default, so a fresh install shows the row
|
|
7
|
+
* without the host's readout cluster. Turning it on mirrors one short value per
|
|
8
|
+
* pill (the output rate, or the cache-hit share) in place of the host's own
|
|
9
|
+
* label.
|
|
10
|
+
*/
|
|
11
|
+
export declare const FEATURE_IDS: readonly ['shell', 'sidebar', 'new-session', 'conversation', 'tool-calls', 'statistics', 'composer-pet', 'composer-stats', 'context-panel'];
|
|
2
12
|
export type FeatureId = typeof FEATURE_IDS[number];
|
|
3
13
|
export type FeatureFlags = Readonly<Record<FeatureId, boolean>>;
|
|
4
14
|
/** Fields of the background-colour section; an empty string means "built-in palette". */
|
|
5
15
|
export declare const APPEARANCE_FIELDS: readonly ['canvas', 'sidebar'];
|
|
6
16
|
/** Fields of the typeface section; an empty string means "system stack". */
|
|
7
17
|
export declare const FONT_FIELDS: readonly ['uiLatin', 'uiCjk', 'code'];
|
|
18
|
+
/** Fields of the view-options section. */
|
|
19
|
+
export declare const VIEW_FIELDS: readonly ['showEmptyGroups'];
|
|
8
20
|
export type AppearanceField = typeof APPEARANCE_FIELDS[number];
|
|
9
21
|
export type FontField = typeof FONT_FIELDS[number];
|
|
22
|
+
export type ViewField = typeof VIEW_FIELDS[number];
|
|
10
23
|
export type AppearanceConfig = Readonly<Record<AppearanceField, string>>;
|
|
11
24
|
export type FontsConfig = Readonly<Record<FontField, string>>;
|
|
25
|
+
export type ViewConfig = Readonly<Record<ViewField, boolean>>;
|
|
12
26
|
export interface StyleConfig {
|
|
13
27
|
readonly enabled: boolean;
|
|
14
28
|
readonly debug: boolean;
|
|
15
29
|
readonly features: FeatureFlags;
|
|
16
30
|
readonly appearance: AppearanceConfig;
|
|
17
31
|
readonly fonts: FontsConfig;
|
|
32
|
+
readonly view: ViewConfig;
|
|
18
33
|
}
|
|
19
34
|
export interface StyleOptions {
|
|
20
35
|
readonly enabled?: boolean;
|
|
@@ -22,11 +37,21 @@ export interface StyleOptions {
|
|
|
22
37
|
readonly features?: Partial<FeatureFlags>;
|
|
23
38
|
readonly appearance?: Partial<Record<AppearanceField, unknown>>;
|
|
24
39
|
readonly fonts?: Partial<Record<FontField, unknown>>;
|
|
40
|
+
readonly view?: Partial<Record<ViewField, unknown>>;
|
|
25
41
|
}
|
|
26
42
|
export declare const DEFAULT_FEATURES: FeatureFlags;
|
|
27
43
|
/** Empty strings keep the built-in palette and the system font stack in charge. */
|
|
28
44
|
export declare const DEFAULT_APPEARANCE: AppearanceConfig;
|
|
29
45
|
export declare const DEFAULT_FONTS: FontsConfig;
|
|
46
|
+
/**
|
|
47
|
+
* The view-options section's defaults.
|
|
48
|
+
*
|
|
49
|
+
* `showEmptyGroups` is off, which means the sidebar hides a Workspace that has
|
|
50
|
+
* no Session under the current filter — the reference's own default for that
|
|
51
|
+
* switch, and the reason the row in the view-options card reads as "off" on a
|
|
52
|
+
* fresh install.
|
|
53
|
+
*/
|
|
54
|
+
export declare const DEFAULT_VIEW: ViewConfig;
|
|
30
55
|
/** Font names longer than this are a pasted paragraph, not a family. */
|
|
31
56
|
export declare const FONT_NAME_MAX_LENGTH = 64;
|
|
32
57
|
/**
|